简单原理剖析-反射方式通过attribute实现字段的动态mapper匹配和赋值

1 篇文章 0 订阅
1 篇文章 0 订阅

问题

当需要根据用户输入值给一个对象的属性赋值时候需要挨个写判断,显得不优雅

例如如下的实例

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实现对字段的绑定,将其绑定到枚举。
  • 当调用setget的时候,通过绑定的Attribute去匹配对应的字段,进行取值和赋值

实现方法及样例

  • 通过NewMethod方法获取到对应类型的枚举,使用这个枚举去setget
  • 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,
    }
}

参考资料

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值