C # Получение Type из строковой переменной и использование его в обобщенном методе - PullRequest
0 голосов
/ 13 февраля 2019

Я хочу иметь возможность получить фактический тип строкового значения, которое я получаю каким-то образом (например, из базы данных), чтобы я мог использовать этот тип в универсальном методе, например DoSomething<Type>().

В моем проекте, У меня есть классы Plane и Car, расположенные в MyCompany.MySolution.Vehicle пространстве имен, например,

- MyCompany.MySolution.Vehicle
  |+Interfaces
  |-Implementations
    |-Car
    |-Plane

Я получаю тип транспортного средства в виде строки.Итак, я получаю строку «Car», что означает, что мне нужно получить Type Car, чтобы я мог использовать этот тип в универсальном методе для его регистрации следующим образом:

MyFactory.Register<Car>(carId)

Итак, MyFactory является статическим классомВызов метода Register ().

Аналогичным образом я получаю строку «Плоскость», что означает, что мне нужно получить тип Plane, чтобы я мог использовать этот тип в общем методе выше для регистрации плоскости.

Я пытался использовать что-то вроде

MyFactory.Register<Type.GetType("MyCompany.MySolution.Vehicle.Implementations.Car")>(carId)

, но это не работает.

Ответы [ 3 ]

0 голосов
/ 14 февраля 2019

Если Register<T> делает что-то подобное

void Register<T>(int id)
{
    _dictionary.Add(typeof(T), ...);
}

Создать не универсальную перегрузку

void Register(Type t, int id)
{
    _dictionary.Add(t, ...);
}

Эта новая перегрузка небезопасна, но создает тип из строкине в любом случае.

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

Обратите внимание, что безопасность типов обеспечивается компилятором, который, конечно, не работает во время выполнения.

0 голосов
/ 14 февраля 2019

Вы можете использовать словарь, который содержит все ваши типы со строковыми ключами:

var d = new Dictionary<String,Type>(); 
d.Add("Car",typeof(Car)); 
d.Add("Plane",typeof(Plane)); 

Тогда, если вы получите строку «Автомобиль» из базы данных, вы можете получить такой тип:

var myType = d["Car"]; 

Затем используйте myType в качестве реального Типа.

0 голосов
/ 13 февраля 2019

Если вы хотите вызвать универсальный метод с параметром Type, сгенерированным во время выполнения, вы могли бы сделать что-то вроде этого:

var vehicleString = "Car";

// use the fully-qualified name of the type here
// (assuming Car is in the same assembly as this code, 
//  if not add a ", TargetAssemblyName" to the end of the string)
var vehicleType = 
    Type.GetType($"MyCompany.MySolution.Vehicle.Implementations.{vehicleString}");

// assuming MyFactory is the name of the class 
// containing the Register<T>-Method
typeof(MyFactory).GetMethod("Register")
    .MakeGenericMethod(vehicleType)
    .Invoke(this);

Рабочий пример

Как примечание:

Это , а не как предполагается использовать дженерики.Я просто указываю на возможность, а не на то, чтобы дать вам идеальный ответ на проблему, которую вы предлагаете.Может быть, вам следует пересмотреть некоторые из ваших архитектурных решений дизайна

...