Мой контекст заключается в том, что я создаю простой фабричный метод для создания экземпляров производных типов данного базового типа. Фабричный метод принимает только параметр типа, т.е. не имеет аргументов. Это, очевидно, возможно с конструкцией if
-else if
:
public Vehicle Create<T>()
{
if (typeof(T) == typeof(Car))
return new Car(); // just an example; could be more complex logic.
else if (typeof(T) == typeof(Truck))
return new Truck(); // just an example; could be more complex logic.
else
throw new ArgumentException(
$"The type {typeof(T).Name} is not known by this method.");
}
К настоящему времени хорошо известно, как использовать сопоставление с образцом в C# (начиная с C# 7.0) для ветвления на основе типа переменной, но это не работает для параметра типа:
switch (T) { ... } // error: "'T' is a type, which is not valid in the given context"
or...
switch (typeof(T))
{
case Car c: ...
// err: "An expression of type 'Type' cannot be handled by a pattern of type 'Car'"
}
Поэтому я хотел бы знать, можно ли использовать switch
для достижения того же результата?
Исследование: я удивлен, что об этом раньше не спрашивали, но я не могу найти. Я нашел это сообщение, в котором есть название и несколько ответов, которые довольно близки, но это работа с (числовыми) типами значений и методами, которые имеют аргумент типа T
-- параметр универсального типа. Точно так же этот пост также использует аргумент .
Dictionary<Type, Func<Vehicle>>
или что-то в этом роде. - person canton7   schedule 09.04.2019RuntimeTypeHandle
для бонусных очков скорости. - person canton7   schedule 09.04.2019where T : new() /* ... */ switch (new T()) { ... }
. - person CodeCaster   schedule 09.04.2019