zoukankan      html  css  js  c++  java
  • C# 类相同属性赋值

    做项目时偶尔B类赋值给A类,碰巧A和B类型很多属性字段名是一样的,或者只是大小写不一样,这是可以利用泛型,反射来写一个自动化赋值的方法。

    下面方法不考虑大小写不一样的情况,如果要考虑,可以使用字符串方法 ToUpper() 、ToLower() 后,对比字段名是否一样。

     public class MapperModel
        {
            /// <summary>
            /// B对象相同属性赋值给A对象, 
            /// </summary>
            /// <typeparam name="A">类型A</typeparam>
            /// <typeparam name="B">类型B</typeparam>
            /// <param name="b">B对象</param>
            /// <returns>返回创建的新A对象</returns>
            public static A Mapper<A, B>(B b)
            {
                A a = Activator.CreateInstance<A>();
                try
                {
                    Type Typeb = b.GetType();//获得类型  
                    Type Typea = typeof(A);
                    foreach (PropertyInfo bp in Typeb.GetProperties())//获得类型的属性字段  
                    {
                        foreach (PropertyInfo ap in Typea.GetProperties())
                        {
                            if (ap.Name == bp.Name)//判断属性名是否相同  
                            {                          
                                if (ap.GetSetMethod()!= null)
                                {
                                    if (bp.GetGetMethod()!=null)
                                    {
                                        ap.SetValue(a, bp.GetValue(b, null), null);//获得b对象属性的值复制给a对象的属性   }
                                    }
                                    
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                return a;
            }
        }

    值得注意的地方,属性到底有没有Get或者Set方法 ?B属性Set访问器是非公共的或不存在 则会赋值时出现异常。同理:A属性如果 Get 访问器是非公共的或不存在,则取值时出现异常

    因此上面使用了 GetSetMethod(),GetGetMethod()做判断。如果Get 、Set 访问器不能正常获取,则返回为null。

    感觉下面的代码写法更可读:省略了一个循环

            /// <summary>
            /// 传入类型B的对象b,将b与a相同名称的值进行赋值给创建的a中        
            /// </summary>
            /// <typeparam name="A">类型A</typeparam>
            /// <typeparam name="B">类型B</typeparam>
            /// <param name="b">类型为B的参数b</param>
            /// <returns>拷贝b中相同属性的值的a</returns>
            public static A MapperTwo<A, B>(B b)
            {
                A a = Activator.CreateInstance<A>();
                try
                {
                    Type Typeb = typeof(B);//获得类型  
                    Type Typea = typeof(A);               
                    foreach (PropertyInfo ap in Typea.GetProperties())
                    {
                        System.Reflection.PropertyInfo bp = Typeb.GetProperty(ap.Name); //获取指定名称的属性
                        if (bp != null) //如果B对象也有该属性
                        {
                            if (ap.GetSetMethod() != null) //判断A对象是否有能用Set方法
                            {
                                if (bp.GetGetMethod() != null) //判断B对象是否有能用Get方法
                                {
                                    ap.SetValue(a, bp.GetValue(b, null), null);//获得b对象属性的值复制给a对象的属性   
                                }
                            }
                        }
                      
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                return a;
            }

    估计我写的就是下面的原理,序列化,反序列化,不区分大小写。当然,不能否定上面的内容。

    public static A MapperTwo<A, B>(B b)
            {
                return Newtonsoft.Json.JsonConvert.DeserializeObject<A>(Newtonsoft.Json.JsonConvert.SerializeObject(b));
            }
    
  • 相关阅读:
    003.Heartbeat MySQL双主复制
    001.常见监控简介
    微服务探索与实践—服务注册与发现
    设计模式之建造者模式
    .NET Core 3.0之深入源码理解Startup的注册及运行
    【译】.NET Core 3.0 Preview 3中关于ASP.NET Core的更新内容
    C#并发编程之异步编程(三)
    设计模式之中介者模式
    设计模式之单例模式
    设计模式之装饰器模式
  • 原文地址:https://www.cnblogs.com/bibi-feiniaoyuan/p/9474236.html
Copyright © 2011-2022 走看看