如何从Type构建泛型类型?

时间:2017-01-01 13:04:54

标签: c# generics reflection types

有没有办法建立像这样的泛型类型?

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

我知道这可能是不可能的。所以要获得解决方法:我想为某些属性的setter创建委托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需要double,我必须通过Action<double>然后才能运行。

我手头有Generic容器类型和Underlying Type。我该如何混合它们?

请注意,我正在处理从类中获取的属性。 一个属性。

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

2 个答案:

答案 0 :(得分:2)

您可以使用Type.MakeGenericType

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

然后您可以创建委托(假设您有MethodInfo名为targetMethodInfo):

Delegate = Delegate.CreateDelegate(genericType, targetMethodInfo);

答案 1 :(得分: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));