用反射创建匿名类型的实例(C#)
C#3.0增加的匿名类型很有魅力,匿名类型很特别,直接继承自object,没有名称定义,属性全都是只读。而且匿名类型的类型之间几乎无法相等,同一个程序集的同样顺序同样类型的参数表,编译器才会判别会同一个类型。
我遇到的情况是从一个不同的程序集返回一个匿名类型的对象,我要将这个对象“复制”为一个本地类型的实例(好吧我仅仅只是为了可以用得上VS的智能提示)。
obj为源对象,targetAnonymousObj为样本对象(本地匿名类型):
public static T ConvertTo<T>(this object obj, T targetAnonymousObj) {
var targetType = targetAnonymousObj.GetType();
var objType = obj.GetType();
var objTypePps = objType.GetProperties();
//var targetConstructor = targetType.GetConstructor(new Type[] { });
List<object> properties = new List<object>();
foreach (var tP in targetType.GetProperties()) {
foreach (var sP in objTypePps) {
if (tP.Name == sP.Name && tP.PropertyType == sP.PropertyType) {
properties.Add(sP.GetValue(obj, null));
}
}
}
var constructors = targetType.GetConstructors();
if (constructors != null) {
ConstructorInfo fitConstructor = null;
foreach (var c in constructors) {
var pars = c.GetParameters();
if (pars.Length == properties.Count) {
fitConstructor = c;
break;
}
}
if (fitConstructor != null) {
return (T)fitConstructor.Invoke(properties.ToArray());
}
}
return targetAnonymousObj;
}
如果不考虑性能,用起来真的很便利:)
/* */
var obj=new {count=7, serviceid=15L };
var myobj=obj.ConvertTo(new{count=0, serviceid=0L}); /* copied! */

评论
暂无评论。发表评论