< p > 可能的重复: < br > c# -有没有比这更好的选择'开关类型'? < / p >
switch (typeof(MyObj)) case Type1: case Type2: case Type3:
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
等。
我曾经做过一次,希望有帮助。
string fullName = typeof(MyObj).FullName; switch (fullName) { case "fullName1": case "fullName2": case "fullName3": }
见另一个答案;这个特性现在已经存在于c#中了
我通常使用类型和委托的字典。
var @switch = new Dictionary<Type, Action> { { typeof(Type1), () => ... }, { typeof(Type2), () => ... }, { typeof(Type3), () => ... }, }; @switch[typeof(MyType)]();
它有点不太灵活,因为你不能摔倒,继续等等。但我也很少这样做。
我很少使用这种形式的switch-case。即便如此,我还是找到了另一种方法来做我想做的事。如果你发现这是完成你需要的唯一方法,我会推荐@Mark H的解决方案。
switch-case
如果这是一种工厂创建决策过程,那么还有更好的方法。否则,我真的不明白你为什么要在一种类型上使用开关。
下面是一个扩展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 }
有这个问题的答案很简单,它使用类型字典来查找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");
在模式匹配方面(包括类型和运行时检查条件),还有这个问题的普遍解决方案:
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)); }