3

好吧,最近我想出了一个(that i really don't know whether it would exist or even work)使用修改后的实例自动更新类属性的想法。为了让我的想法更清楚一点,我将在下面的代码中解释它。

//The first (Main) instance of the class
Employee carl = new Employee();
carl.Name = "Carl";
carl.Age = 20;
carl.Salary = 7000;

//Here is the same employee data collected from the database a year after...
Employee carl_one_year_later = new Employee();
carl_one_year_later.Age = 21;
carl_one_year_later.Salary = 10000;

//Here comes the idea... I wanna dynamically merge the new collected data to the current main instance of the employee, without missing out the unupdated data ex : his name
employee1 = employee2; //using this seems to overwrite the Name Field with null...

有人可能会说你可以通过这样做来简单地实现这一点:

carl.Age = carl_one_year_later.Age;
carl.Salary = carl_one_year_later.Salary;

但是,我想要一种动态的方法来在 1 行代码中执行此操作并让 C#set为我处理属性,如果我们有一个我们不想每次都设置它的属性的大型类,它可能会派上用场是一一更新的。

注意:我希望我成功地提供了我的想法的清晰形象,如果您在理解我到底需要什么方面发现任何问题,请告诉我。

4

5 回答 5

2
using System;
using System.Reflection;

public class Test
{
    public class Employee
    {
        public String Name{get;set;}
        public int Age{get;set;}
        public int Salary{get;set;}
    }
    public static void Main()
    {
        Employee e1 = new Employee{Name="Old", Age=20, Salary=1000};
        Employee e2 = new Employee{Age=30, Salary=5000};

        Copy(e2, e1);

        Console.WriteLine(e1.Name+" "+ e1.Age+" "+e1.Salary );
    }

    public static void Copy<T>(T from, T to)
    {
        Type t = typeof (T);
        PropertyInfo[] props = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
        foreach (PropertyInfo p in props) {
            if (!p.CanRead || !p.CanWrite) continue;

            object val = p.GetGetMethod().Invoke(from, null);
            object defaultVal = p.PropertyType.IsValueType ? Activator.CreateInstance(p.PropertyType) : null;
            if (null != defaultVal && !val.Equals(defaultVal)) {
                p.GetSetMethod().Invoke(to, new[] {val});
            }
        }
    }
}
于 2013-10-16T03:35:14.370 回答
1

您可以制作CopyTo扩展方法,如下所示:

public static class ObjectExtensions
{
    public static void CopyTo<T>(this T fromObj, T toObj)
    {
        foreach(var p in typeof(T).GetProperties()) 
        {
            p.SetValue(toObj, p.GetValue(fromObj, null), null);
        }
    }
}

并称它为:

carl_one_year_later.CopyTo(carl);

虽然,老实说,应该进行更多检查,但最好使用AutoMapper之类的东西。

于 2013-10-16T03:34:07.043 回答
0

检查 ICloneable 或 MemberwiseClone(除非你需要做一个深拷贝。然后检查一个对象映射器,如 Automapper、ValueInjecter 或编写你自己的自定义对象序列化水合器)

http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx

MemberwiseClone 方法通过创建一个新对象,然后将当前对象的非静态字段复制到新对象来创建一个浅拷贝。

http://msdn.microsoft.com/en-us/library/system.icloneable.aspx

AutoMapper 的替代品

于 2013-10-16T04:23:04.240 回答
0
public static class ObjectExtensions
    {
        public static void CopyTo<T>(this T fromObj, T toObj)
        {
            foreach (var p in typeof(T).GetProperties())
            {
                if(p.GetValue(fromObj) == null)
                {
                    continue;
                }
                p.SetValue(toObj, p.GetValue(fromObj, null), null);
            }
        }
    }

与上面的答案相同,但只是在“foreach”中添加了“if”以跳过空值

于 2021-12-12T18:37:04.430 回答
-1

这个想法本身对我来说似乎很奇怪..

我,我自己,宁愿这样做:

//The first (Main) instance of the class
Employee carl = new Employee();
carl.Name = "Carl";
carl.Age = 20;
carl.Salary = 7000;

//Here we get Carl from the database
Employee carl = GetFromDatabase("Carl") //Illustration
carl.Age = 21;
carl.Salary = 10000;

你的代码就像说现在卡尔和明年卡尔是一个完全不同的人,巧合的是拥有所有这些相同的属性。

虽然如果真的需要做,我确实更喜欢 Automapper ..

于 2013-10-16T05:09:41.677 回答