2017-01-01 133 views
0

有没有什么办法可以构建这样的泛型类型?如何从Type创建泛型类型?

Type underlyingType = propertyInfo.PropertyType; 
Type genericType = typeof(Action<underlyingType>); 

我知道这可能是不可能的。所以得到解决方法:我想创建一个委托Action<T>设置一些属性。

var type = propertyInfo.PropertyType; 
var defaultVal = type.IsValueType ? Activator.CreateInstance(type) : null; 

var setter = (Action<object>)propertyInfo 
    .GetSetMethod(true) 
    .CreateDelegate(typeof(Action<object>), this); 

var resetter = new Action(() => setter(defaultVal)); 
return resetter; 

这不起作用。因为我必须通过完全匹配类型。如果Property setter需要两倍,我必须通过Action<double>然后它的工作。

我有通用的容器类型和底层类型。我怎么能混合他们?


请注意,我的工作团一类采取属性不是单一财产。

var props = GetType().GetProperties(Flags); 

回答

2

您可以使用Type.MakeGenericType

Type underlyingType = propertyInfo.PropertyType; 
Type genericType = typeof(Action<>).MakeGenericType(underlyingType); 

然后,您可以创建委托(假设你有一个名为MethodInfotargetMethodInfo):

Delegate = Delegate.CreateDelegate(genericType, targetMethodInfo); 
+0

非常好,干净的方法。我会将此标记为答案,因为它回答了它自身的问题。 (现在我脑海中另一个问题是'DynamicInvoke'更好或者是'SetValue',或者有更好的方法。) –

0

我能够做到这一点,我怎么打电话DynamicInvoke,它似乎是缓慢的任何方式。

var ptype = propertyInfo.PropertyType; 
var defaultVal = ptype.IsValueType ? Activator.CreateInstance(ptype) : null; 
var type = Type.GetType($"System.Action`1[{ptype}]"); 
var setter = prop.GetSetMethod(true).CreateDelegate(type, this); 
var resetter = new Action(() => setter.DynamicInvoke(defaultVal)); 
return resetter; 

所以也许这种方法更好。

var ptype = propertyInfo.PropertyType; 
var defaultVal = ptype.IsValueType ? Activator.CreateInstance(ptype) : null; 
var resetter = new Action(() => propertyInfo.SetValue(this, defaultVal));