2017-01-01 2 views
0

Есть ли способ построить такой общий тип?Как создать общий тип из типа?

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

Я знаю, что это будет невозможно. поэтому, чтобы получить обходные пути: я хочу создать делегат Action<T> для setter некоторых свойств.

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; 

Это не работает. потому что я должен пройти точный тип соответствия. Если свойство setter принимает двойной, я должен пройти Action<double>, тогда он работает.

У меня есть общий тип контейнера и базовый тип в руке. как я могу их смешивать?


Обратите внимание, что я работаю на группы свойств, взятых из класса. не отдельное имущество.

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

ответ

2

Вы можете использовать Type.MakeGenericType:

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

Вы можете создать делегат (если у вас есть MethodInfo имени targetMethodInfo):

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)); 
Смежные вопросы