当前位置:编程学习 > C#/ASP.NET >>

请教,如何手动设置从System.Attribute派生类?


 private static T ConvertXml<T>(XElement xElement) where T : new()
        {
            var model = new T();
            xElement.Elements().ToList().ForEach(els =>
                                                     {
                                                         var itemNew = model.GetType();
                                                         var property = itemNew.GetProperty(els.Name.LocalName);
                                                         object obj = null;
                                                         if (property != null)
                                                         {
                                                             if (!string.IsNullOrEmpty(els.Value))
                                                             {
                                                                 obj = ConvertModelValue(property.PropertyType.FullName,
                                                                                   els.Value);
                                                                 property.GetCustomAttributes(typeof(ColumnAttribute),
                                                                                              true).OfType
                                                                     <ColumnAttribute>().FirstOrDefault().IsUse = true;  //设置要只用的属性   TODO:  设置值,但无用

                                                             }
                                                             property.SetValue(model, obj, null);
                                                         }
                                                     });
            return model;

        }
/// <summary>
    /// 自定义列特性
    /// </summary>
    public class ColumnAttribute : System.Attribute
    {
        /// <summary>
        /// 是否有效列
        /// </summary>
        public virtual bool IsUse { get; set; }
    }


在获取属性值的时候,是获取不到值的。 请教为何? 求赐教 --------------------编程问答-------------------- 求赐教 ...   --------------------编程问答-------------------- 你是写了一个单独的属性子类,但是T 是ConvertXml这个。两回事啊,
东边下雨,关西边什么事?没联系。
你除非把T所属的类,再改一下,继承ConvertXml,取个别名。然后可以反射出。 --------------------编程问答-------------------- 没人在 ???     求赐教啊 .... --------------------编程问答-------------------- 有点晕,帮顶一下 --------------------编程问答--------------------    property.GetCustomAttributes(typeof(ColumnAttribute),
                                                                                              true).OfType
                                                                     <ColumnAttribute>().FirstOrDefault().IsUse = true;  /
 property和 ColumnAttribute有什么关联??? --------------------编程问答-------------------- 或者property再什么时候被ColumnAttribute标志了 --------------------编程问答-------------------- 2 楼. 这位仁兄 
我的意图是写成通用,如果用到继承,那么是有局限性的.  "什么东边下雨,关西边事? " 这个不明白. 麻烦说详细点. 谢谢!  --------------------编程问答--------------------

public class Common<T> where T : new()
    {
 public bool AutoAdd(T modelContext)
        {
            modelContext.GetType().GetProperties().ToList().ForEach(item =>
            {
                if (item != null && item.GetValue(modelContext, null) != null)
                {
                    var columnAttribute = item.GetCustomAttributes(typeof(ColumnAttribute), true).OfType<ColumnAttribute>().FirstOrDefault();
                    if (columnAttribute.IsUse)
                    {
                         //TODO:条件满足,这里面是我将要做的事情。
                    }
                }
            });
            return true;
        }
}
--------------------编程问答-------------------- 5 楼
这是一个XML文件的操作, 进行导入的时候! 
我要读节点下面的数据,然后进行实体模型化.
"或者property再什么时候被ColumnAttribute标志了"
也就是当我读到是那些需要节点,我才进行数据保存操作. --------------------编程问答-------------------- item.GetCustomAttributes(typeof(ColumnAttribute), true)我觉得 这个就是 个null ,不知道是不是? --------------------编程问答-------------------- 你的实体类有应用自定义特性了么?


public class Model
{
   [Column(IsUsed = true)]
   string Name{get;set;}
}

类似上面的代码有么? --------------------编程问答-------------------- 有, 但未设置类中属性的值。  以你给出的例子来说, 也就是为设置 IsUsed 值。 只是有标记。 未给默认值。
引用 11 楼  的回复:
你的实体类有应用自定义特性了么?

C# code

public class Model
{
   [Column(IsUsed = true)]
   string Name{get;set;}
}


类似上面的代码有么?
--------------------编程问答-------------------- 这个不是空值。  因为有给实体类中的属性进行标记。 只是未给出默认值。 
因为目的是为了,需要的时候进行赋值,所以才没有给默认值。
现在的问题就是现在手动设置属性值的时候, 有问题。 
引用 10 楼  的回复:
item.GetCustomAttributes(typeof(ColumnAttribute), true)我觉得 这个就是 个null ,不知道是不是?
--------------------编程问答-------------------- public virtual bool IsUse { get; set; }
那是不是这个 红色的关键字的 问题啊 ...赋值应该没有问题 --------------------编程问答-------------------- 这个是虚拟的 IsUse     虚对象是不能实例化的,,,可能是这个关键字的问题吧...你去掉试试 --------------------编程问答-------------------- 关于virtual 关键字,只是对它的一种定义。  对赋值应该是没有影响的。
引用 14 楼  的回复:
public virtual bool IsUse { get; set; }
那是不是这个 红色的关键字的 问题啊 ...赋值应该没有问题
--------------------编程问答-------------------- 楼主的操作是设置啊?你确定每次获取到的attribute的实例都是同一个吗。 --------------------编程问答--------------------
引用 17 楼  的回复:
楼主的操作是设置啊?你确定每次获取到的attribute的实例都是同一个吗。


嗯。是的!我是需要进行手动设置属性值。
获取到的attribute的实例,应该是同一个、在使用Linq做循环的时候,应该Lock的吧。
而且代码也是明确设定当前属性下的标记值。 
代码也有贴出来,也可以帮忙瞧瞧。  --------------------编程问答-------------------- 是不是同一实例你先测试过再说
另可以用一个静态的Dictionary<PropertyInfo, bool>来记录状态。 --------------------编程问答--------------------
引用 19 楼  的回复:
是不是同一实例你先测试过再说
另可以用一个静态的Dictionary<PropertyInfo, bool>来记录状态。


在出现问题的时候,我已经进行过跟踪过,是同一个。所以不是这个问题。 --------------------编程问答-------------------- 自己看结果



namespace Lab
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine();
            var a = GetAtrribute();
            Console.WriteLine(a.Flag);
            a.Flag = true;
            Console.WriteLine(a.Flag);
            var b = GetAtrribute();
            Console.WriteLine(b.Flag);
            Console.WriteLine(object.ReferenceEquals(a, b));
        }
        
        static XAtrribute GetAtrribute() 
        {
            return typeof(X)
                .GetProperties()
                .FirstOrDefault()
                .GetCustomAttributes(typeof(XAtrribute), true)
                .FirstOrDefault() as XAtrribute;
        }
    }

    public class X 
    {
        [XAtrribute]
        public string Name { get; set; }
    }

    public class XAtrribute : Attribute 
    {
        public bool Flag { get; set; }
    }
}

--------------------编程问答--------------------
引用 21 楼  的回复:
自己看结果

C# code


namespace Lab
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine();
            var a = GetAtrribute();
            Console.……


Friend . 
你这段代码和我首先给出的代码没差别啊。我只是没有用变量接收,而直接进行了赋值操作。 
当设置完属性值后,你是用的变量接收。输出来的变量是及时的值。 问题是当你设置完属性值之后,去获取这个属性值,却是获取不到的。  --------------------编程问答--------------------
引用 22 楼  的回复:
问题是当你设置完属性值之后,去获取这个属性值,却是获取不到的。 


唉,这么直白怎么就理解不了呢,两次获取attribute得到的是两个不同的attribute实例,任你怎么玩弄其中一个的实例成员,另一个都没有任何影响。 --------------------编程问答-------------------- 可能.net不支持动态修改特性

可以试试用条件编译,生成不同版本的Model

或者派生新的子Model --------------------编程问答-------------------- 特性在编译时嵌入元数据中,一般情况下是只读的 --------------------编程问答--------------------
引用 23 楼  的回复:
唉,这么直白怎么就理解不了呢,两次获取attribute得到的是两个不同的attribute实例,任你怎么玩弄其中一个的实例成员,另一个都没有任何影响。



class Program
    {
        static void Main(string[] args)
        {
            var x = new X();
            x.GetType().GetProperty("Name").SetValue(x,"zhangsan",null);
            Console.WriteLine(x);
            var a = GetAtrribute(x);
            Console.WriteLine(a.Flag);
            a.Flag = true;
            Console.WriteLine(a.Flag);
            var b = GetAtrribute(x);
            Console.WriteLine(b.Flag);
            Console.WriteLine(x.Name);
            Console.WriteLine(object.ReferenceEquals(a, b));
        }

        static XAtrribute GetAtrribute(X x)
        {
            return x.GetType()
                .GetProperties()
                .FirstOrDefault()
                .GetCustomAttributes(typeof(XAtrribute), true)
                .FirstOrDefault() as XAtrribute;
        }
        public class X
        {
            [XAtrribute]
            public string Name { get; set; }
        }

        public class XAtrribute : Attribute
        {
            public bool Flag { get; set; }
        }
    }

初始化X类!
这样可以直接设置属性值,可以设置Name属性的值,却不能设置属性标记类的属性值。
同一个实例,为什么不能对同一个实例进行赋值和取值操作呢? 
或者求赐教,该如何进行赋值操作?  --------------------编程问答--------------------
引用 25 楼  的回复:
特性在编译时嵌入元数据中,一般情况下是只读的


这样 ...  只读? 
要伤心死叻! --------------------编程问答--------------------
引用 24 楼  的回复:
可以试试用条件编译,生成不同版本的Model

或者派生新的子Model


什么意思? 求详解. --------------------编程问答--------------------
引用 26 楼  的回复:
这样可以直接设置属性值,可以设置Name属性的值,却不能设置属性标记类的属性值。
同一个实例,为什么不能对同一个实例进行赋值和取值操作呢?  


 因为根本就不是同一个实例好不好,没想法了. object.ReferenceEquals(a, b) 你得到的是true吗? --------------------编程问答--------------------
引用 29 楼  的回复:
引用 26 楼  的回复:

这样可以直接设置属性值,可以设置Name属性的值,却不能设置属性标记类的属性值。
同一个实例,为什么不能对同一个实例进行赋值和取值操作呢?

 因为根本就不是同一个实例好不好,没想法了. object.ReferenceEquals(a, b) 你得到的是true吗?


这里说的不同实例,是指attribute的实例。不是attribute被标记的那个类型的实例. --------------------编程问答--------------------
引用 29 楼  的回复:
 因为根本就不是同一个实例好不好,没想法了. object.ReferenceEquals(a, b) 你得到的是true吗?


False。
可是奇怪啊、 GetAtrribute()方法传入的是同一个X类。  X类的属性值没有改变,而X类属性的标记类的却是新的一个实例。 这是为什么呢?? --------------------编程问答--------------------
引用 31 楼  的回复:
False。
可是奇怪啊、 GetAtrribute()方法传入的是同一个X类。 X类的属性值没有改变,而X类属性的标记类的却是新的一个实例。 这是为什么呢??


typeof(类型) 跟 类型实例.GetType()得到的结果是一样的,按照你的理解,第一种方式根本就没实例化,哪来实例呢?元数据只不过是告诉框架该如何初始化attribute,每调用一次GetCustomAttributes获取到的都是不同的实例,而且跟那个被标记的成员毫不相关。 --------------------编程问答--------------------
引用 32 楼  的回复:
typeof(类型) 跟 类型实例.GetType()得到的结果是一样的,按照你的理解,第一种方式根本就没实例化,哪来实例呢?元数据只不过是告诉框架该如何初始化attribute,每调用一次GetCustomAttributes获取到的都是不同的实例,而且跟那个被标记的成员毫不相关。


没有查阅过GetCustomAttributes方法的具体使用,只是通过VS中注释,而使用的.
哎!对于小生我,没文化真可怕啊。 

那么能否赐教,如何给标记类中的属性值赋值呢?? 这也是我问题的最根本!! 求解决啊.


--------------------编程问答--------------------
引用 33 楼  的回复:


同19楼所说,这里不用attribute,用一个静态的Dictionary<PropertyInfo, bool>来记录状态就好了,如果状态不是全局有效的,就不用静态,定义一个上下文对象。 --------------------编程问答--------------------
引用 34 楼  的回复:
同19楼所说,这里不用attribute,用一个静态的Dictionary<PropertyInfo, bool>来记录状态就好了,如果状态不是全局有效的,就不用静态,定义一个上下文对象。


当然,这个想法在出现这个问题的时候,我就已经想到叻.
但是,因为考虑到比较麻烦(个人认为的麻烦咯),就没有那样去做,在寻求当前这种方法...
难道就没有人手动设置过标记类的属性值??? 天哪. --------------------编程问答-------------------- 也可以通过attribute的方法访问静态对象,只是这样反而变的更麻烦了。 --------------------编程问答--------------------
引用 36 楼  的回复:
也可以通过attribute的方法访问静态对象,只是这样反而变的更麻烦了。


哎哎哎哎 ... 
竟然没有人有过这样的经历! 
话说,难道这个问题要沉入大海叻 ....  --------------------编程问答-------------------- 关键是找对解决的方法,不是即使不合适也要硬生生地把某种模式套进去用。 --------------------编程问答-------------------- class DemoClass {
    static void Main(string[] args) {
        AnimalTypeTestClass testClass = new AnimalTypeTestClass();
        Type type = testClass.GetType();
        // Iterate through all the methods of the class.
        foreach(MethodInfo mInfo in type.GetMethods()) {
            // Iterate through all the Attributes for each method.
            foreach (Attribute attr in
                Attribute.GetCustomAttributes(mInfo)) {
                // Check for the AnimalType attribute.
                if (attr.GetType() == typeof(AnimalTypeAttribute))
                    Console.WriteLine(
                        "Method {0} has a pet {1} attribute.",
                        mInfo.Name, ((AnimalTypeAttribute)attr).Pet);
            }

        }
    } --------------------编程问答--------------------
引用 39 楼  的回复:
class DemoClass {
    static void Main(string[] args) {
        AnimalTypeTestClass testClass = new AnimalTypeTestClass();
        Type type = testClass.GetType();
        // Iterate through all ……


???  --------------------编程问答-------------------- --------------------编程问答-------------------- MSDN 上的例子 ,你去看看吧...
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,