工作中遇到这样的代码:
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函数里面的,一段是外面的。加起来就可以了,来自网上,自己写也就这些东西。