用反射创建匿名类型的实例(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! */ 
暂无评论

评论

暂无评论。

发表评论

*必填

*必填 (不会被公开)