简体   繁体   中英

Clean way to Compare / Copy between Similar Classes

We have two classes that have the exact same public accessors (and many of them) but are from different areas in the object hierarchy; we have a need to copy and compare between these two objects. We could manually write a copy constructor and a comparison operator which compares the values of the same-named accessors, but it seems as though there's got to be a better way to do this using reflection and LINQ.

Example: we have class ClassA which has 70 accessors; we also have class ClassB which has 70 accessors, which are defined to be the same name and type as ClassA's accessors.

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

What I'd like is a simple way of using reflection to discover all of the public accessors of ClassA, and use those names to set the values of the respective accessor on ClassB to the value of the accessor on ClassA. Roughly, in psuedocode:

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

And, of course, the same thing could be used for testing equality between the two classes. My knowledge of C# reflection and LINQ is not good enough to know how to get this done, but I'd swear it's something relatively simple.

How about using AutoMapper :

Mapper.CreateMap<ClassA, ClassB>();

and then:

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

It's basically an implementation of your pseudo-code.

your rough pseudocode is somewhat accurate. Let me clean it up a little:

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

Obviously, this doesn't do error checking, and stuff like that, but it should do the job.

You could do it in Linq, but I don't think it would be cleaner.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM