Reputation: 1886
Let's say we have two classes with same names and types of fields:
class A
{
private int x;
private string y;
}
class B
{
private int x;
private string y;
}
A a = new A();
B b = new B();
a.x = 5;
a.y = "xxx";
Is it possible to "copy" or "assign" a into b? I mean is there simple way to do it like "b=a" ?
Upvotes: 3
Views: 266
Reputation: 11964
The simplest way to do what you want is to use the Automapper library.
In this case you add map for these two classes:
Mapper.CreateMap<A,B>();
and then use method Map
:
A a = new A();
//initialize a
B b = Mapper.Map(a);
Upvotes: 4
Reputation: 7475
Also you can use Json.NET:
A a = new A();
string s = JsonConvert.SerializeObject(a);
B b = JsonConvert.DeserializeObject<B>(s);
Upvotes: 1
Reputation: 210352
There's no simple way to do it in C#.
You can, however, dynamically generate your own methods via ILGenerator
or Expression Trees to do this copying for you. (It's not easy if you haven't done it before though.)
Example:
using System;
using System.Reflection;
using System.Reflection.Emit;
public class Foo
{
private int a;
public Foo(int a) { this.a = a; }
}
public class Program
{
private int a;
private static void Main()
{
var prog1 = new Foo(1);
var prog2 = new Program() { a = 2 };
TypeHelper<Foo, Program>.Copy(prog1, prog2);
}
}
public static class TypeHelper<T1, T2> where T1 : class where T2: class
{
public delegate void CopyAction(T1 from, T2 to);
public static readonly CopyAction Copy = new Converter<Type, CopyAction>(t1 =>
{
var method = new DynamicMethod(string.Empty, null, new Type[] { t1, typeof(T2) }, t1, true);
var gen = method.GetILGenerator();
foreach (var field in t1.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldfld, field);
gen.Emit(OpCodes.Stfld, typeof(T2).GetField(field.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
}
return (CopyAction)method.CreateDelegate(typeof(CopyAction));
})(typeof(T1));
}
Upvotes: 0
Reputation: 6876
I'd suggest you use reflection:
void Main()
{
A foo = new A();
B bar = new B();
CopyValues(foo, bar);
}
public void CopyValues(object f, object t)
{
Type fr = f.GetType();
Type target = t.GetType();
var bindingFlags = BindingFlags.Public| BindingFlags.NonPublic | BindingFlags.Instance;
foreach(FieldInfo source in fr.GetFields(bindingFlags))
{
FieldInfo fi = target.GetField(source.Name, bindingFlags);
if(fi != null)
fi.SetValue(t, source.GetValue(f));
}
}
Upvotes: 3
Reputation: 14511
I think you can do that with Marshal.StructureToPtr
and Marshal.PtrToStructure
.
See example in Marshal.StructureToPtr Method (MSDN)
Upvotes: -1