你会如何改进这种浅层复制课程?

时间:2009-01-22 17:04:38

标签: c# reflection shallow-copy

我用一个静态方法编写了一个类,它将属性值从一个对象复制到另一个对象。它并不关心每个对象的类型,只关心它们具有相同的属性。它做我需要的,所以我不会进一步设计它,但你会做出哪些改进?

以下是代码:

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);

4 个答案:

答案 0 :(得分:6)

您的DTO是否可序列化?我希望如此,在这种情况下:

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

但请注意,我并不同意这种一般方法。我希望有一份强有力的合同来复制每个DTO实施的DTO。

答案 1 :(得分:4)

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

  • 您的大部分工作都是通用类型,而不仅仅是通用方法。这允许您缓存属性,以及允许类型推断。类型推断对于“TFrom”参数很重要,因为它允许使用匿名类型。

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

答案 2 :(得分: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;
}

答案 3 :(得分:1)

如果传递的是共享某些属性但不是全部属性的对象,请确定要执行的操作。在尝试设置其值之前,请检查From对象中To对象中是否存在该属性。当你来到一个不存在的财产时,做“正确的事”。如果所有公共属性都需要相同,那么您需要检查是否已在To对象上设置了所有这些属性,并处理了未适当的情况。

我还建议您可能希望使用属性来装饰需要复制的属性并忽略其他属性。这将允许您更轻松地在两个不同对象之间来回切换,并继续维护派生的一些公共属性,而不是存储在业务对象上。