C#中类成员变量的定义分为两种:域(field)与属性(property),属性为公有变量,以get,set访问器进行访问,域多为私有变量,非get、set访问器进行访问,如以下类的的域为成员name,而属性为val.
class Customer {
#region fields
public string name;
#endregion
#region property
public int val { get; set; }
#endregion
};
当我们获得一个类对象时,我们就可以通过反射机制来获取该类的成员及内容:
Customer obj = new Customer();
obj.name = "123456";
obj.val = 3;
Type objtype = obj.GetType();
PropertyInfo[] l = objtype.GetProperties();
foreach (var item in l) {
Console.WriteLine("{0}:{1}",item.Name,item.GetValue(obj,null));
}
FieldInfo[] fields = objtype.GetFields();
foreach (var item in fields) {
Console.WriteLine("{0}:{1}", item.Name, item.GetValue(obj));
}
我们也可以创建该类的对象:
//Customer cs = (Customer)Program.getObj(obj);
static object getObj(object obj)
{
Type objtype = Nullable.GetUnderlyingType(obj.GetType()) ?? obj.GetType();
PropertyInfo[] l = objtype.GetProperties();//objtype
object instance = Activator.CreateInstance(objtype);
foreach (var item in l)
{
Console.WriteLine("{0}:{1}", item.Name, item.GetValue(obj, null));
item.SetValue(instance, item.GetValue(obj, null), null);
}
FieldInfo[] fields = objtype.GetFields();
foreach (var item in fields)
{
Console.WriteLine("{0}:{1}", item.Name, item.GetValue(obj));
item.SetValue(instance, item.GetValue(obj));
}
return instance;
}
利用这些反射特性就可以在运行中生成新的对象或构造属性Attribute验证器了。如果我们将类写成如下格式:
[AttributeUsage(AttributeTargets.Field)]
class Check : Attribute {
public int MaxLength { get; set; }
};
class Customer {
#region fields
[Check(MaxLength=5)]
public string name;
#endregion
#region property
public int val { get; set; }
#endregion
};
通过Check来验证字段的合法性,利用反射来进行统一验证:
FieldInfo[] fields = objtype.GetFields();
foreach(var item in fields) {
foreach (Attribute a in item.GetCustomAttributes(typeof(Check),false))
{
Check c = (Check)a;
Console.WriteLine("field:{0},max length:{1}", item.Name, c.MaxLength);
}
}
最后一个类的验证工作就可以这样方便的实现了。