工作中遇到這樣的代碼:
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函數裏面的,一段是外面的。加起來就可以了,來自網上,自己寫也就這些東西。