C# Attribute 特性 描述 反射技術(類的屬性)

工作中遇到這樣的代碼:

public class Exportable : Attribute
{
    public string Name;
     public bool WriteFile { get;set; }
}
public class ColumnAttribute : Attribute
    {
        public ColumnAttribute();
        public ColumnAttribute(string name);

        public string Name { get; }
        public int Order { get; set; }
        public string TypeName { get; set; }
    }
public class My_Entity:AbsEntity,INotifyPropertyChanged;
{
        [Exportable("工作特徵")]
        [Column("ONE")]
        public string one { get; set; }
        [Exportable("第一種")]
        [Column("TWO")]
        public string TWO { get; set; }
        [Exportable("第二種")]
        [Column("THREE")]
        public int? Three { get; set; }
        [Exportable("Three", true)]
        [Column("Four")]
        public byte[] Four { get; set; }
        [Column("Five")]
        public string Five { get; set; }
        [NotMapped]
        public T<IT>
       //當然還有很多東西,沒寫出來。
}

最主要的還是用的時候

//隨便貼個代碼1
var pros = type.GetProperties();
var proList = pros.Where(p => p.GetCustomAttributes(typeof(Exportable), false).FirstOrDefault() != null);
//隨便貼個代碼2
var projectIdPro = proList.FirstOrDefault(p => (p.GetCustomAttributes(typeof(Exportable), false).FirstOrDefault() as Exportable).ProjectId);
//隨便貼個代碼3
Exportable desc = m.GetCustomAttributes(typeof(Exportable), true).FirstOrDefault() as Exportable;

第三段代碼的結果就是,pros獲取的是My_Entity所有的屬性,而proList獲取的是所有被Exportable標記的屬性。(這裏面用了LINQ語句。可以參考其他的。)
可以標記一個類中的屬性,是不是很好玩。


比如看到了一個很好玩的例子

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AttributesClass
{
    class Program
    {
        static void Main(string[] args)
        {
            Old();
        }
        [Obsolete("Don't use Old method, use New method", true)]
        static void Old() { }
        static void New() { }
    }
}

比如上面這個代碼,系統會告訴你:錯誤 1 “AttributesClass.Program.Old()”已過時:“Don’t use Old method, use New method”


開始總結了。
一般來說,如果我們要用自定義的Attributes,都會派生於System.Attribute類。比如上面的例子。而且,一般都會用Attribute作爲特性類的後綴,如上第一段代碼,奇怪的是你在後面標記的時候,不用寫Attribute,比如我上面寫的類名ColumnAttribute但是我只用Column標記。往裏面添加東西就先不說。

下面說說AtributeUage類,在attribute類中,本身就用這個東西來標記了,也就是說,我們能爲我們自定義的特徵類定義attributes.它表達了一個自定義的類能被怎樣使用。AtributeUage類提供了三個屬性:
1.ValidOn
不太懂,借用別人的:這組我們能把自定義attribute類放置其上的語言元素被放在枚舉器AttributeTargets 中。可以這麼用:[AttributeUsage((AttributeTargets)4, AllowMultiple = false, Inherited = false )],4代表就是“class”元素,其它諸如1代表“assembly”,16383代表“all”等等)或者”.”操做符綁定幾個AttributeTargets 值。(譯者注:默認值爲AttributeTargets.All)
2.AllowMultiple
該標誌表示我們自定義attribte能在同一語言上使用多次。(屬性爲bool類型,默認值爲false,也就是隻能用一次。)
3.Inherited
控制繼承的,屬性爲bool類型,默認值false,代表不能繼承。


屬性,反射技術

名詞都是專業名詞,看起來高大上,其實懂了就還好。
屬性在上面寫的代碼中有體現。比如
Type type = aa.GetType();//獲取類型
System.Reflection.PropertyInfo propertyInfo = type.GetProperty(“Property1”);
propertyInfo.SetValue(aa, 5, null);//給對應屬性賦值
int value = (int)propertyInfo.GetValue(aa, null);//獲取值


下面貼一個完整的代碼demo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AttributesClass
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass obj = new MyClass();
            Type t = typeof(MyClass);
            //循環賦值 
            string  i = "what";
            foreach (var item in t.GetProperties())
            {
                item.SetValue(obj, i, null);
                i += 1;
            }
            //單獨賦值 
            t.GetProperty("one").SetValue(obj, "11111111", null);
            //循環獲取 
            StringBuilder sb = new StringBuilder();
            foreach (var item in t.GetProperties())
            {
                sb.Append("類型:" + item.PropertyType.FullName + " 屬性名:" + item.Name + " 值:" + item.GetValue(obj, null) + "\n");
            }
            //單獨取值 
            string  five = Convert.ToString(t.GetProperty("one").GetValue(obj, null));
            sb.Append("單獨取five的值:" + five);
            string result = sb.ToString();
            Console.WriteLine(result);
            Console.ReadKey(); 
        }
        public class MyClass
        {
            public string one { set; get; }
            public string two { set; get; }
            public string three { set; get; }
            public string four { set; get; }
        }
    }
}

運行後的結果如下

類型:System.String 屬性名:one 值:11111111
類型:System.String 屬性名:two 值:what1
類型:System.String 屬性名:three 值:what11
類型:System.String 屬性名:four 值:what111
單獨取one的值:11111111

獲取方法和獲取屬性一樣
無非改爲t.GetMethods();

 #region 實驗二Method
            Type myType = (typeof(MyTypeClass));
            // Get the public methods.
            MethodInfo[] myArrayMethodInfo = myType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            Console.WriteLine("\nThe number of public methods is {0}.", myArrayMethodInfo.Length);
            // Display all the methods.
            DisplayMethodInfo(myArrayMethodInfo);
            // Get the nonpublic methods.
            MethodInfo[] myArrayMethodInfo1 = myType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            Console.WriteLine("\nThe number of protected methods is {0}.", myArrayMethodInfo1.Length);
            // Display information for all methods.
            DisplayMethodInfo(myArrayMethodInfo1);
            Console.ReadKey();
            #endregion 實驗二
 public class MyTypeClass
        {
            public void MyMethods1()
            {
            }
            public int MyMethods2()
            {
                return 3;
            }
            protected String MyMethods3()
            {
                return "hello";
            }
        }
        public static void DisplayMethodInfo(MethodInfo[] myArrayMethodInfo)
        {
            // Display information for all methods.
            for (int i = 0; i < myArrayMethodInfo.Length; i++)
            {
                MethodInfo myMethodInfo = (MethodInfo)myArrayMethodInfo[i];
                Console.WriteLine("\nThe name of the method is {0}.", myMethodInfo.Name);
            }
        }

一段是main函數裏面的,一段是外面的。加起來就可以了,來自網上,自己寫也就這些東西。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章