如何改进这个浅复制类?

6
我编写了一个类,其中包含一个静态方法,可以将一个对象的属性值复制到另一个对象中。它不关心每个对象的类型,只要它们具有相同的属性即可。它已经能够满足我的需求,所以我不会再做更多的改进。但是你会对此有什么改进建议吗?
以下是代码:
public class ShallowCopy
{
    public static void Copy<From, To>(From from, To to)
        where To : class
        where From : class
    {
        Type toType = to.GetType();
        foreach (var propertyInfo in from.GetType().GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance))
        {
            toType.GetProperty(propertyInfo.Name).SetValue(to, propertyInfo.GetValue(from, null), null);
        }
    }
}

我使用它的方式如下:
EmployeeDTO dto = GetEmployeeDTO();
Employee employee = new Employee();
ShallowCopy.Copy(dto, employee);

我们如何将其与List<T>或包含多个List<T>列表的对象一起使用? - billsecond
1
那将是一个“深度”复制。基本上与上面相同,但递归地查找具有可从IEnumerable继承的PropertyTypePropertyInfo。显然,您需要处理清除目标可枚举和其他事情。 - Neil Barnwell
4个回答

6

您的DTO是否可序列化?我认为应该是这样的,如果是这样的话:

MemberInfo[] sm = FormatterServices.GetSerializableMembers(typeof(From));
object[] data = FormatterServices.GetObjectData(from, sm);
FormatterServices.PopulateObjectMembers(to, sm, data);

但请注意,我并不完全同意这种一般的方法。我更喜欢在DTO中实现每个DTO的强约定。


4
  • 将您的类型参数名称更改为符合命名约定,例如TFrom和TTo,或TSource和TDest(或TDestination)。

  • 在泛型类型中完成大部分工作,而不仅仅是在泛型方法中完成。这使您可以缓存属性,并允许类型推断。类型推断对于“TFrom”参数非常重要,因为它将允许使用匿名类型。

  • 您可以通过动态生成代码来执行属性复制并将其保留在委托中,该委托对“from”类型有效,从而使其速度极快。或者可能为每个from/to对生成代码,这意味着实际复制根本不需要使用反射!(准备代码将是每对类型的一次性费用,但希望您不会有太多对。)


2
一个新的方法,它会在返回之前创建一个新的 To 实例并调用 Copy() 方法,可能会很有用。
像这样:
public static To Create<From, To>(From from)
    where To : class, new()
    where From : class
{
    var to = new To();
    Copy(from, to);
    return to;
}

1
决定当传递的对象具有某些但不是全部共享属性类型时要做什么。在尝试设置其值之前,请检查From对象中是否存在属性在To对象中的存在。对于不存在的属性,应该执行“正确的操作”。如果所有公共属性需要相同,则需要检查是否在To对象上设置了所有属性,并适当地处理未设置所有属性的情况。
我还建议您可能希望使用属性来装饰需要复制并忽略其他属性的属性。这将使您更轻松地在两个不同的对象之间转换,并继续保持一些派生而不是存储在业务对象上的公共属性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接