问题
当需要根据用户输入值给一个对象的属性赋值时候需要挨个写判断,显得不优雅
例如如下的实例
public class Person{
public int ScoreEnglish{get;set;}
public int ScoreMath{get;set;}
public int ScorePhysical{get;set;}
}
public enum ScoreType
{
English,
Math,
Physical
}
public static void Main(){
var p = new Person(){};
SetPersonValue(p,ScoreType.English,88); // 常规设置方法
Console.WriteLine(p.ScoreEnglish); // 88
}
public static void SetPersonValue(Person p,ScoreType type,int value){
// 这里不够优雅,因为意味着每次修改枚举都要到这里来改代码
switch(type){
case ScoreType.English:p.ScoreEnglish = value;break;
case ScoreType.Math:p.ScoreMath = value;break;
case ScoreType.Physical:p.ScorePhysical = value;break;
}
}
动态赋值的总体思路
- 通过创建
Attribute
实现对字段的绑定,将其绑定到枚举。- 当调用
set
或get
的时候,通过绑定的Attribute
去匹配对应的字段,进行取值和赋值
实现方法及样例
- 通过
NewMethod
方法获取到对应类型的枚举,使用这个枚举去set
和get
NewMethod
实现判断当前类型的字段是哪个,并通过反射去操作这个字段PropertyTypeAttribute
是定义了每个字段归属于哪个枚举的类型,NewMethod
基于该方法实现。- 最后在
Main
方法实现了测试,测试一个对象的根据类型动态赋值到不同的字段
public namespace Test
{
static void Main(string[] args)
{
var c = new C() { PropertyA = "A", PropertyB = "B", };
var propertyType = NewMethod(typeof(C), PropertyType.A);
Console.WriteLine(propertyType.GetValue(c));
propertyType.SetValue(c, "A01");
Console.WriteLine(propertyType.GetValue(c));
}
private static PropertyInfo NewMethod(Type type, PropertyType propertyType)
{
PropertyInfo[] propertys = type.GetProperties();
foreach (var property in propertys)
{
var attr = (PropertyTypeAttribute)Attribute.GetCustomAttribute(
property,
typeof(PropertyTypeAttribute)
);
if (attr != null)
{
if (attr.Pet == propertyType)
{
return property;
}
}
}
return null;
}
public class C
{
[PropertyType(PropertyType.A)]
public string PropertyA { get; set; }
[PropertyType(PropertyType.B)]
public string PropertyB { get; set; }
}
public class PropertyTypeAttribute : Attribute
{
// The constructor is called when the attribute is set.
public PropertyTypeAttribute(PropertyType pet)
{
thePet = pet;
}
// Keep a variable internally ...
protected PropertyType thePet;
// .. and show a copy to the outside world.
public PropertyType Pet
{
get { return thePet; }
set { thePet = value; }
}
}
public enum PropertyType
{
A,
B,
}
}