可能重复:
C# - Is there a better alternative than this to 'switch on type'?
C#不支持切换对象的类型。模拟这个的最佳模式是什么:
switch (typeof(MyObj))
case Type1:
case Type2:
case Type3:
谢谢!
答案 0 :(得分:172)
我通常使用类型和代表的字典。
var @switch = new Dictionary<Type, Action> {
{ typeof(Type1), () => ... },
{ typeof(Type2), () => ... },
{ typeof(Type3), () => ... },
};
@switch[typeof(MyType)]();
它不太灵活,因为你无法通过案件,继续等等。但我很少这样做。
答案 1 :(得分:25)
Switch case on type c#对这个问题有一个简单的答案,它使用类型字典来查找lambda函数。
以下是如何使用
var ts = new TypeSwitch()
.Case((int x) => Console.WriteLine("int"))
.Case((bool x) => Console.WriteLine("bool"))
.Case((string x) => Console.WriteLine("string"));
ts.Switch(42);
ts.Switch(false);
ts.Switch("hello");
}
在switch / pattern matching idea
的模式匹配(类型和运行时检查条件)方面,还有一个通用的解决方案。 var getRentPrice = new PatternMatcher<int>()
.Case<MotorCycle>(bike => 100 + bike.Cylinders * 10)
.Case<Bicycle>(30)
.Case<Car>(car => car.EngineType == EngineType.Diesel, car => 220 + car.Doors * 20)
.Case<Car>(car => car.EngineType == EngineType.Gasoline, car => 200 + car.Doors * 20)
.Default(0);
var vehicles = new object[] {
new Car { EngineType = EngineType.Diesel, Doors = 2 },
new Car { EngineType = EngineType.Diesel, Doors = 4 },
new Car { EngineType = EngineType.Gasoline, Doors = 3 },
new Car { EngineType = EngineType.Gasoline, Doors = 5 },
new Bicycle(),
new MotorCycle { Cylinders = 2 },
new MotorCycle { Cylinders = 3 },
};
foreach (var v in vehicles)
{
Console.WriteLine("Vehicle of type {0} costs {1} to rent", v.GetType(), getRentPrice.Match(v));
}
答案 2 :(得分:15)
更新: 这已在C#7.0中使用pattern matching
修复switch (MyObj)
case Type1 t1:
case Type2 t2:
case Type3 t3:
旧答案:
这是C#游戏中的漏洞,还没有银弹。
你应该谷歌'访客模式',但它可能有点沉重,但你仍然应该知道。
以下是使用Linq的另一个问题:http://community.bartdesmet.net/blogs/bart/archive/2008/03/30/a-functional-c-type-switch.aspx
否则沿着这些方面可以提供帮助
// nasty..
switch(MyObj.GetType.ToString()){
case "Type1": etc
}
// clumsy...
if myObj is Type1 then
if myObj is Type2 then
等。
答案 3 :(得分:4)
我做了一次解决方法,希望它有所帮助。
string fullName = typeof(MyObj).FullName;
switch (fullName)
{
case "fullName1":
case "fullName2":
case "fullName3":
}
答案 4 :(得分:3)
我在极少数情况下使用过switch-case
这种形式。即便如此,我还找到了另一种方法来做我想做的事。如果你发现这是完成你需要的唯一方法,我会推荐@Mark H的解决方案。
如果这是一种工厂创建决策过程,那么有更好的方法可以做到这一点。否则,我真的不明白你为什么要在一个类型上使用开关。
这是一个扩展Mark解决方案的小例子。我认为这是一种使用类型的好方法:
Dictionary<Type, Action> typeTests;
public ClassCtor()
{
typeTests = new Dictionary<Type, Action> ();
typeTests[typeof(int)] = () => DoIntegerStuff();
typeTests[typeof(string)] = () => DoStringStuff();
typeTests[typeof(bool)] = () => DoBooleanStuff();
}
private void DoBooleanStuff()
{
//do stuff
}
private void DoStringStuff()
{
//do stuff
}
private void DoIntegerStuff()
{
//do stuff
}
public Action CheckTypeAction(Type TypeToTest)
{
if (typeTests.Keys.Contains(TypeToTest))
return typeTests[TypeToTest];
return null; // or some other Action delegate
}