#c# #c#-8.0
#c# #c #-8.0
Вопрос:
Возможно ли создать switch expression
в C # 8 на основе типа ввода?
Мои входные классы выглядят так:
public class A1
{
public string Id1 {get;set}
}
public class A2 : A1
{
public string Id2 {get;set}
}
public class A3 : A1
{
public string Id3 {get;set;}
}
Я хочу запускать разные методы на основе типа ввода ( A1
, A2
, или A3
):
var inputType = input.GetType();
var result = inputType switch
{
inputType as A1 => RunMethod1(input); // wont compile,
inputType as A2 => RunMethod2(input); // just showing idea
inputType as A3 => RunMethod3(input);
}
Но это не сработает. Есть идеи, как создать выражение переключения или переключения на основе типа ввода?C
Комментарии:
1. Попробуйте сначала запустить переключатель с наиболее специфичным типом (A3) и перейти к наименее специфичному (A1)
2. Но мой код не компилируется, я просто показал идею
3. О, да, я вижу это сейчас, замените как есть
Ответ №1:
Вы могли бы использовать сопоставление с образцом, сначала проверив наиболее конкретные типы.
GetType
не требуется:
var result = input switch
{
A2 _ => RunMethod1(input),
A3 _ => RunMethod2(input),
A1 _ => RunMethod3(input)
};
Однако более OO-подход заключался бы в определении метода для самих типов:
public class A1
{
public string Id1 { get; set; }
public virtual void Run() { }
}
public class A2 : A1
{
public string Id2 { get; set; }
public override void Run() { }
}
Тогда это просто:
input.Run();
Комментарии:
1. Хорошая идея, но ваш код не компилируется. Я получаю эту ошибку:
The Pattern has already been handled by previous arm of switch expression
2. @michasaucer Для меня он отлично компилируется: dotnetfiddle.net/1dGHUz
3. Ваш ответ тоже компилируется для меня… Итак, теперь мне нужно выяснить, почему это не используется в моем сценарии (я только что вставил базовый пример здесь в SO). Спасибо!
4.@JohnathanBarclay если вы измените экземпляр на
A2
илиA3
он не будет компилироваться, см. Второй пункт «примечания» в моем ответе.5. @Jamiec Да, я, вероятно, должен был явно ввести переменную в моей скрипке.
Ответ №2:
Вы можете, но в подобной иерархии наследования вам нужно начинать с наиболее конкретного и двигаться вниз к наименьшему:
A1 inputType = new A2();
var result = inputType switch
{
A3 a3 => RunMethod(a3),
A2 a2 => RunMethod(a2),
A1 a1 => RunMethod(a1)
};
Обратите внимание, что
inputType
является экземпляром, а не экземпляромType
inputType
вводится как базовый класс, но может быть экземпляром любого A1-3. В противном случае вы получите ошибку компилятора.
Живой пример: https://dotnetfiddle.net/ip2BNZ