Я пытаюсь создать экземпляр универсального класса с помощью Текстового объекта.
В основном у меня будет набор объектов переменных типов во времени выполнения, и так как нет никакого пути наверняка для знания то, что вводит, они точно будут, я думаю, что должен буду использовать Отражение.
Я работал над чем-то как:
Type elType = Type.GetType(obj);
Type genType = typeof(GenericType<>).MakeGenericType(elType);
object obj = Activator.CreateInstance(genType);
Который является хорошо и хорош. ^ ___^
Проблема, я хотел бы получить доступ к методу своего GenericType <> экземпляр, который я не могу, потому что это вводится как класс объекта. Я не могу найти способ бросить его obj в определенный GenericType <>, потому что это было проблемой во-первых (т.е. я просто не могу вставить что-то как:)
((GenericType<elType>)obj).MyMethod();
Как нужно пойти о занятии этой проблемой?
Большое спасибо! ^ ___^
Вам придется продолжать использовать Reflection для вызова фактического метода:
// Your code
Type elType = Type.GetType(obj);
Type genType = typeof(GenericType<>).MakeGenericType(elType);
object obj = Activator.CreateInstance(genType);
// To execute the method
MethodInfo method = genType.GetMethod("MyMethod",
BindingFlags.Instance | BindingFlags.Public);
method.Invoke(obj, null);
Для получения дополнительной информации см. Type.GetMethod и MethodBase.Invoke .
В C # 3.5 вы должны использовать Type.GetMethod
и MethodInfo.Invoke
для вызова метода.
В C # 4 можно использовать ключевое слово dynamic
и выполнить привязку к методу во время выполнения.
Создав экземпляр, просто выполните:
MethodInfo method = genType.GetMethod("MyMethod");
method.Invoke(obj, null);
Как только вы начнете игру с отражением, вам нужно будет пройти ее до конца. Тип неизвестен во время компиляции, поэтому вы не можете его преобразовать. Вам нужно будет вызвать метод путем отражения:
obj.GetType().InvokeMember(
"MyMethod",
BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod,
null,
obj,
null
);
Самый простой подход - извлечь неуниверсальный супертип (базовый класс или интерфейс) из GenericType, который содержит методы, которые вы хотите предоставить для этой цели:
class GenericType<T> : GenericBase { ... }
class GenericBase { abstract void MyMethod(); }
В противном случае используйте отражение для доступа к самому методу как предложено @Aaronaught.
Если вы знаете сигнатуру методов, которые хотите вызвать, вы можете не только использовать MethodInfo. Invoke()
, как показано в других примерах здесь, но и создать делегат, который позволяет более эффективно вызывать методы (если вам нужно вызвать один и тот же метод несколько раз), используя Delegate.CreateDelegate()
.
Я не уверен, насколько сильно различаются ваши типы и есть ли у вас контроль над методами, которые вы будете в них вызывать, но может быть полезно создать интерфейс, который определяет, какой набор функций вы собираетесь использовать. звонит. Итак, после создания экземпляра вы можете преобразовать его в интерфейс и вызывать любые нужные вам функции.
так что создайте свой стандартный интерфейс (который вам нужно будет реализовать в каждом типе, если у вас есть контроль над ними):
interface IMyInterface
{
void A();
int B();
}
class One : IMyInterface
{
...
implement A and B
...
}
Type elType = Type.GetType(obj);
Type genType = typeof(GenericType<>).MakeGenericType(elType);
IMyInterface obj = (IMyInterface)Activator.CreateInstance(genType);
obj.A();