【问题标题】:Clean way to Compare / Copy between Similar Classes在相似类之间进行比较/复制的简洁方法
【发布时间】:2010-11-10 18:27:25
【问题描述】:

我们有两个类具有完全相同的公共访问器(并且其中有很多),但来自对象层次结构中的不同区域;我们需要在这两个对象之间进行复制和比较。我们可以手动编写一个复制构造函数和一个比较运算符来比较同名访问器的值,但似乎必须有更好的方法来使用反射和 LINQ。

示例:我们有一个 ClassA 类,它有 70 个访问器;我们还有 ClassB 类,它有 70 个访问器,它们被定义为与 ClassA 的访问器相同的名称和类型。

public class ClassA 
{
int OneInt {get; set;}
int TwoInt {get; set;}
...
string OneString {get; set;}
string AnotherString {get; set;}
}

public class ClassB
{
int OneInt {get; set;}
int TwoInt {get; set;}
...
string OneString {get; set}
string AnotherString {get; set;}
}

我想要的是一种使用反射来发现 ClassA 的所有公共访问器的简单方法,并使用这些名称将 ClassB 上的相应访问器的值设置为 ClassA 上的访问器的值。粗略地说,在伪代码中:

foreach (string accName in ClassA.Accessors[])
    BInstance.Accessors[accName].Value = AInstance.Accessors[accName].Value;

当然,同样的东西也可以用来测试两个类之间的相等性。我对 C# 反射和 LINQ 的了解不足以知道如何完成这项工作,但我发誓这是相对简单的。

【问题讨论】:

    标签: c# linq reflection accessor


    【解决方案1】:

    AutoMapper怎么样:

    Mapper.CreateMap<ClassA, ClassB>();
    

    然后:

    ClassA classA = ...
    ClassB classB = Mapper.Map<ClassA, ClassB>(classA);
    

    它基本上是您的伪代码的实现。

    【讨论】:

    • 不错;这绝对是一个选择,尽管我仍然怀疑在 vanilla C# 中有一种“聪明”的方法可以完成这项工作。
    • 是的,当然是使用反射。但是,如果您希望它非常聪明(例如处理 null 的情况,不兼容的类型,...),您将需要编写大量的 vanilla C# 代码。那么,当有人已经做过、测试过、记录过、将其打包到可重用的程序集中、测量其性能时,为什么还要编写它……这样您现在就可以专注于应用程序的实际业务而不是做管道工作?跨度>
    • 你的观点很好,但我认为学习技术是有价值的,即使它们可能已经在外部库中实现了;这是一个以实用的方式深入了解语言的问题。
    • @McWafflestix,完全同意。这对学术目的有好处。但是在我认为您所问的实际应用程序中,在编写所有这些代码之前我会三思而后行:-)
    • 有趣点;这实际上是针对单元测试代码的,因此任何故障都会立即被捕获,而不是用于生产,但是您的观点很好;在没有广泛的边缘案例测试的情况下,我会在实际生产代码中谨慎使用它。
    【解决方案2】:

    您的粗略伪代码有些准确。让我清理一下:

    foreach (var propertyA in typeof(ClassA).GetProperties())
    {
        var propertyB = typeof(ClassB).GetProperty(propertyA.Name);
        var valueA = propertyA.GetValue(objectA, null);
        propertyB.SetValue(objectB, valueA, null);
    }
    

    显然,这并没有进行错误检查之类的东西,但它应该可以完成这项工作。

    你可以在 Linq 中做,但我不认为它会更干净。

    【讨论】:

    • 我喜欢那个;这很清楚。我知道我使用 pcode 处于正确的位置! :)
    猜你喜欢
    • 1970-01-01
    • 2012-11-24
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 2011-05-10
    • 2021-03-30
    • 2014-07-05
    相关资源
    最近更新 更多