C# 在C中,在运行时将属性更改为只读

C# 在C中,在运行时将属性更改为只读,c#,.net,C#,.net,我正在创建一个属性类,它采用泛型。这个泛型将是用户创建的一个类,类似于配置文件中的appSettings部分。它们为每个键创建一个属性,该属性允许它们将该键映射到该字段。当他们使用自己的类作为泛型实例化我的类时,我会在他们的类中查找我的属性,当找到我的属性时,我会使用他们设置的名称来查找appSetting键,然后将该属性值设置为appSetting值,同时将其转换为他们设置属性的任何类型 因此,基本上这是一个映射属性,它在配置文件中强烈地键入appSettings。它使映射在类中完成,而不是用

我正在创建一个属性类,它采用泛型。这个泛型将是用户创建的一个类,类似于配置文件中的appSettings部分。它们为每个键创建一个属性,该属性允许它们将该键映射到该字段。当他们使用自己的类作为泛型实例化我的类时,我会在他们的类中查找我的属性,当找到我的属性时,我会使用他们设置的名称来查找appSetting键,然后将该属性值设置为appSetting值,同时将其转换为他们设置属性的任何类型

因此,基本上这是一个映射属性,它在配置文件中强烈地键入appSettings。它使映射在类中完成,而不是用户必须在代码中内联完成映射并将其弄乱。漂亮干净的映射

我的最后一步是,我想将它们的属性标记为只读,但我不知道如何做,因为PropertyInfo类的CanWrite属性本身是只读的


两件事,一件是C不允许泛型属性类。所以这是行不通的

其次,不能在运行时将属性更改为只读。反射用于检查加载类型的元数据,而不是更改元数据


您可以自己支持属性,但这是一项更大的工作。

这可能是您希望使用Emit并代理它的地方。您无法在运行时修改元数据……甚至从未听说过Emit,但它似乎是一个全新的世界。我会更深入地挖掘,有什么理由反对投票吗?我做错了什么?很高兴知道这一点,以供将来参考。抱歉,我应该说得更清楚,这不是属性类,而是在app.config中获取强类型appSettings的实际库类。属性类与此不同,但这将完成读取配置文件和根据使用my属性装饰的属性确定用户传入的通用类型中要获取哪些属性的所有工作。在运行时不能将其更改为只读,这有点糟糕。你说你自己还这些房子是什么意思?组件类中还有只读属性,这不会将所述属性更改为只读吗?要在运行时将属性标记为只读,可以使用Reflection.Emit或Mono.Cecil生成代码。但我看不到属性的私有集访问器有任何问题。为什么需要完全只读的修改器?您想避免任何人通过反射设置属性吗?但我认为这是好的,如果有人尝试它,所以它确实是必要的him@Serg046一般来说,我认为app.config在很大程度上是只读的,因此这些属性也应该是只读的。如果不是这样的话,这并不是时代的结束,只是试图在app.config理念的意义上变得更标准。私有集访问器不允许从外部上下文更改值。所以它是只读的,不是吗?是的,对于该属性,但这不是用户创建的类,而是用户使用的我的库类。用户创建的类是到appSettings的映射,他们可以手动将每个字段设置为只读,但我只是尝试应用规则,而不是让他们自己做。因此他们称之为:var config=new StrongConfiguration;Console.WriteLineconfig.AppSettings.ARCPurgeDays,其中TestConfig是模仿app.config的appSetting部分的类
/// <summary>
    /// This class will fill in the fields of the type passed in from the config file because it's looking for annotations on the type
    /// </summary>
    public class StrongConfiguration<T> where T: class
    {
        // this is read only
        public T AppSettings { get; private set; }

        public StrongConfiguration()
        {
            AppSettings = (T)Activator.CreateInstance(typeof(T));

            // find properties in this type that have the ConfigAttribute attribute on them
            var props = from p in AppSettings.GetType().GetProperties()
                        let attr = p.GetCustomAttributes(typeof(ConfigAttribute), true)
                        where attr.Length == 1
                        select new { Property = p, Attribute = attr.First() as ConfigAttribute };

            // find the config setting from the ConfigAttribute value on each property and set it's value casting to the propeties type
            foreach (var p in props)
            {
                var appSettingName = ConfigurationManager.AppSettings[p.Attribute.ConfigName];

                var value = Convert.ChangeType(appSettingName, p.Property.PropertyType);

                p.Property.SetValue(AppSettings, value);

                // todo: I want to set this propety now as read-only so they can't change it but not sure how
            }
        }
    }