Общий тип из строкового значения - PullRequest
5 голосов
/ 17 сентября 2011

Я получил пользовательский класс, который полагается на универсальный тип T для передачи. Я знаю только, какой это тип в строковой форме, потому что именно так он и отправляется. Я искал вокруг, но не могу найти именно то, что мне нужно. Я могу проанализировать строковое значение для типа, но мне нужно проанализировать его для ... чего-то, что я могу передать в качестве универсального параметра.


Я переписал свою проблему, как таковую:

// Classes structure
namespace Mynamespace
{
    public interface IRequest
    {
    }

    public interface IHandler<T> where T : IRequest
    {
        void Handle(T item);
    }

    public class MyRequest : IRequest
    {
    }

    public class MyHandler : IHandler<MyRequest>
    {
        void Handle(MyRequest item)
        {
        }
    }
}

// The info I get, and I know typeString is a IRequest
string typeString = "My";
object requestItem = [insert xml parsing here];

// I then create a handler, to handle the request
Type typeHandler = Type.GetType("Mynamespace." + typeString + "Handler");
var handler = Activator.CreateInstance(typeHandler);

Type typeRequest = Type.GetType("Mynamespace." + typeString + "Request");

// what I want to do:
handler.Handle(requestItem);

Я не могу этого сделать, потому что handler и requestItem - просто объекты Поэтому мне нужно разобрать 'обработчик' в 'typeHandler' и requestItem в 'typeRequest'

Edit: Я понял это, я использовал InvokeMember для доступа к нему. :)

typeHandler.InvokeMember("Handle", BindingFlags.InvokeMethod, null, handler, new[] { requestItem });

Ответы [ 3 ]

9 голосов
/ 17 сентября 2011

Вам нужно Type.MakeGenericType:

Type typeArgument = Type.GetType(string.Format("Mynamespace.{0}", typeString));
Type template = typeof(MyClass<>);

Type genericType = template.MakeGenericType(typeArgument);

object instance = Activator.CreateInstance(genericType);

Обратите внимание, что вы не можете привести это к определенному MyClass<T>, потому что вы не знаете T - но это будет экземпляр нужного класса во время выполнения.

4 голосов
/ 17 сентября 2011
Type closedType = typeof(MyClass<>).MakeGenericType(myGeneric);
object obj = Activator.CreateInstance(closedType);

Обратите внимание, что если у вас нет неуниверсального интерфейса или базового типа, очень сложно общаться с этим типом объекта (если вы не обманываете, используя dynamic). Например, не универсальный интерфейс может быть полезен:

var obj = (ISomeInterface)Activator.CreateInstance(closedType);
obj.SomeMethodOnTheNonGenericInterface();
0 голосов
/ 17 сентября 2011

Я понял, я использовал InvokeMember для доступа к нему. :)

typeHandler.InvokeMember("Handle", BindingFlags.InvokeMethod, null, handler, new[] { requestItem });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...