Как динамически вызвать универсальный метод, основанный на отображении в словаре? - PullRequest
0 голосов
/ 06 марта 2010

У меня есть метод

String Foo<T> where T: WebControl

Теперь у меня есть строка типа "гиперссылка". То, что нужно, это вызвать Foo<Hyperlink> на основе сопоставления строки со стандартным.

Как должен выглядеть словарь?

Это не:

private Dictionary<string, Type> _mapping = new Dictionary<string, Type>()
{
      {"hyperlink", typeof(HyperLink)}
};

Я хочу получить к нему доступ, как Foo<_mapping[mystring]> это возможно? Если да, то как должен выглядеть словарь?

Редактировать : Принято решение

String _typename = "hyperlink";
MethodInfo _mi = typeof(ParserBase).GetMethod("Foo");
Type _type = _mapping[_typename];
MethodInfo _mig = _mi.MakeGenericMethod(_type);
return (String)_mig.Invoke(this, new object[] { _props }); // where _props is a dictionary defined elsewhere
// note that the first parameter for invoke is "this", due to my method Foo is not static

Ответы [ 3 ]

1 голос
/ 06 марта 2010

Это невозможно. Generics поддерживает только привязку компиляции.

1 голос
/ 06 марта 2010

Нет, вы не можете этого сделать.Ваш универсальный тип хочет создать себя во время компиляции, но он не знает, какой это тип во время выполнения.Однако вы можете использовать отражение.

Type untypedGeneric = typeof(Foo<>);
Type typedGeneric = untypedGeneric.MakeGenericType(_mapping[mystring]);
1 голос
/ 06 марта 2010

То, что вы хотите, невозможно, так как это будет время выполнения (например, словарь может содержать что-нибудь позже).

Если вы хотите сгенерировать его вручную во время выполнения, вы можете сделать это, но вы не получите проверку во время компиляции, которую имеет C # для обобщений. Вы можете сделать это через MethodInfo.MakeGenericMethod .

Как это:

var m = typeof(MyClass);
var mi = ex.GetMethod("Foo");
var mig = mi.MakeGenericMethod(_mapping["hyperlink"]);

//Invoke it
mig .Invoke(null, args);
...