Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there anything built into .NET/C# for copying values between objects?

Tags:

c#

.net

copy

Suppose you have 2 classes like so:

public class ClassA {
    public int X { get; set; }
    public int Y { get; set; }
    public int Other { get; set; }
}

public class ClassB {
    public int X { get; set; }
    public int Y { get; set; }
    public int Nope { get; set; }
}

Now imagine you have an instance of each class and you want to copy the values from a into b. Is there something like MemberwiseClone that would copy the values where the property names match (and of course is fault tolerant -- one has a get, and the other a set, etc.)?

var a = new ClassA(); var b = new classB();
a.CopyTo(b); // ??

Something like this is pretty easy in a language like JavaScript.

I'm guessing the answer is no, but maybe there is a simple alternative too. I have written a reflection library to do this, but if built in to C#/.NET at a lower level would probably be more efficient (and why re-invent the wheel).

like image 241
lucidquiet Avatar asked Jan 23 '12 18:01

lucidquiet


People also ask

Is .NET built on C?

. NET was fully written in C and C++ because the base was in assembly language.

Is .NET related to C?

NET framework is written in C# (if not all of it). It's syntax is simply the next progression of the C language, thus transitioning from C++ to C# shouldn't be too difficult. It's a paradigm shift with a lot of things, but at least the syntax is often familiar. Any .

Does .NET only use C#?

NET Framework applications are written in C#, F#, or Visual Basic and compiled to Common Intermediate Language (CIL). The Common Language Runtime (CLR) runs . NET applications on a given machine, converting the CIL to machine code. See Architecture of .


2 Answers

There's nothing in the framework for object-object mapping but there's a very popular library out there that does this: AutoMapper.

AutoMapper is a simple little library built to solve a deceptively complex problem - getting rid of code that mapped one object to another. This type of code is rather dreary and boring to write, so why not invent a tool to do it for us?

By the way, just for learning, here's a simple way you can implement what you want. I haven't tested it thoroughly, and it's nowhere as robust / flexible / performant as AutoMapper, but hopefully there's something to get out of the general idea:

public void CopyTo(this object source, object target)
{
    // Argument-checking here...

    // Collect compatible properties and source values
    var tuples = from sourceProperty in source.GetType().GetProperties()
                 join targetProperty in target.GetType().GetProperties() 
                                     on sourceProperty.Name 
                                     equals targetProperty.Name

                 // Exclude indexers
                 where !sourceProperty.GetIndexParameters().Any()
                    && !targetProperty.GetIndexParameters().Any()

                 // Must be able to read from source and write to target.
                 where sourceProperty.CanRead && targetProperty.CanWrite

                 // Property types must be compatible.
                 where targetProperty.PropertyType
                                     .IsAssignableFrom(sourceProperty.PropertyType)

                 select new
                 {
                     Value = sourceProperty.GetValue(source, null),
                     Property = targetProperty
                 };

    // Copy values over to target.
    foreach (var valuePropertyTuple in tuples)
    {
        valuePropertyTuple.Property
                          .SetValue(target, valuePropertyTuple.Value, null);

    }
}
like image 91
Ani Avatar answered Sep 29 '22 18:09

Ani


There's nothing like this in .NET that I'm aware of, but one library that is able to do this (and much more) is AutoMapper. For your case, something like:

_mapper.Map<A, B> (a, b);
like image 26
Pete Avatar answered Sep 28 '22 18:09

Pete