public static T ConvertType<T>(Student s) { dynamic sx = null; if (typeof(T) == typeof(Student1)) { sx = new Student1(); //非公有部分负值 sx.id = s.id; sx.name = s.name; } else if (typeof(T) == typeof(Student2)) { sx = new Student2(); //非公有部分负值 //省略.... } //共有部分负值 if (sx != null) { //省略.... } return (T)sx; }
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text;namespace ConsoleApplication1 { class Class1 { public int ID { get; set; } public string Name { get; set; } public string Commant { get; set; } } class Class2 { public int ID { get; set; } public string Name { get; set; } public string Note { get; set; } public override string ToString() { return string.Format("ID:{0}, Name:{1}, Note:{2}", ID, Name, Note); } } class Program { static Func<TSource, TResult> CloneObj<TSource, TResult>() { var p = Expression.Parameter(typeof(TSource)); var r = Expression.Variable(typeof(TResult), "result"); var letr = Expression.Assign(r, Expression.New(typeof(TResult).GetConstructor(Type.EmptyTypes))); var copyexprs = typeof(TSource).GetProperties().Join(typeof(TResult).GetProperties(), x => x.Name, y => y.Name, (x, y) => new { x, y }) .Select(x => Expression.Assign(Expression.MakeMemberAccess(r, x.y), Expression.MakeMemberAccess(p, x.x))).ToList(); var block = Expression.Block(new ParameterExpression[] { r }, new Expression[] { r, letr }.Concat(copyexprs).Concat(new Expression[] { r }).ToArray()); var lambda = Expression.Lambda(block, p); return lambda.Compile() as Func<TSource, TResult>; } static void Main(string[] args) { var FromClass1ToClass2 = CloneObj<Class1, Class2>(); Class1 c1 = new Class1() { ID = 1, Name = "A", Commant = "This is A." }; Class2 c2 = FromClass1ToClass2(c1); Console.WriteLine(c2); } } }来点元编程。
解释下:这个例子比较简单,没有考虑复杂类型的递归拷贝,以及判断类型是否相同的情况。这里利用表达式树产生一个Lambda表达式,并且编译。 var FromClass1ToClass2 = CloneObj<Class1, Class2>(); 产生了一个叫FromClass1ToClass2的本地方法,以后调用这个方法不用进行反射,所以效率和你手工赋值完全相等。所谓元编程就是指面向编程而编程,我们的代码像处理数据一样地产生了新的代码,而产生的代码才实现你的最终用途。
{
dynamic sx = null;
if (typeof(T) == typeof(Student1))
{
sx = new Student1();
//非公有部分负值
sx.id = s.id;
sx.name = s.name;
}
else if (typeof(T) == typeof(Student2))
{
sx = new Student2();
//非公有部分负值
//省略....
}
//共有部分负值
if (sx != null)
{
//省略....
}
return (T)sx;
}
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;namespace ConsoleApplication1
{
class Class1
{
public int ID { get; set; }
public string Name { get; set; }
public string Commant { get; set; }
} class Class2
{
public int ID { get; set; }
public string Name { get; set; }
public string Note { get; set; }
public override string ToString()
{
return string.Format("ID:{0}, Name:{1}, Note:{2}", ID, Name, Note);
}
} class Program
{
static Func<TSource, TResult> CloneObj<TSource, TResult>()
{
var p = Expression.Parameter(typeof(TSource));
var r = Expression.Variable(typeof(TResult), "result");
var letr = Expression.Assign(r, Expression.New(typeof(TResult).GetConstructor(Type.EmptyTypes)));
var copyexprs = typeof(TSource).GetProperties().Join(typeof(TResult).GetProperties(), x => x.Name, y => y.Name, (x, y) => new { x, y })
.Select(x => Expression.Assign(Expression.MakeMemberAccess(r, x.y), Expression.MakeMemberAccess(p, x.x))).ToList();
var block = Expression.Block(new ParameterExpression[] { r }, new Expression[] { r, letr }.Concat(copyexprs).Concat(new Expression[] { r }).ToArray());
var lambda = Expression.Lambda(block, p);
return lambda.Compile() as Func<TSource, TResult>;
} static void Main(string[] args)
{
var FromClass1ToClass2 = CloneObj<Class1, Class2>();
Class1 c1 = new Class1() { ID = 1, Name = "A", Commant = "This is A." };
Class2 c2 = FromClass1ToClass2(c1);
Console.WriteLine(c2);
}
}
}来点元编程。
var FromClass1ToClass2 = CloneObj<Class1, Class2>();
产生了一个叫FromClass1ToClass2的本地方法,以后调用这个方法不用进行反射,所以效率和你手工赋值完全相等。所谓元编程就是指面向编程而编程,我们的代码像处理数据一样地产生了新的代码,而产生的代码才实现你的最终用途。
看了下简介,应该和我的原理一样。lz可以把我的代码看成AutoMapper的一个原型版。