C# switch on type
本问题已经有最佳答案,请猛点这里访问。
Possible Duplicate:
C# - Is there a better alternative than this to 'switch on type'?
C不支持打开对象类型。模拟这个的最佳模式是什么:
1 2 3 4 |
谢谢!
我通常使用类型和委托的字典。
1 2 3 4 5 6 7 |
这有点不太灵活,因为你不能掉进箱子,继续等等,但我很少这样做。
对于这个问题,有一个简单的答案,在类型C的开关盒上,它使用类型字典来查找lambda函数。
这是它的使用方法
1 2 3 4 5 6 7 8 9 | 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"); } |
在开关/模式匹配思想下,对于模式匹配(类型和运行时检查条件)也有一个通用的解决方案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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)); } |
更新:这在C 7.0中得到了修正,模式匹配
1 2 3 4 | 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
否则,沿着这条线的东西会有帮助
1 2 3 4 5 6 7 8 |
等。
我做过一次,希望能有所帮助。
1 2 3 4 5 6 7 8 | string fullName = typeof(MyObj).FullName; switch (fullName) { case"fullName1": case"fullName2": case"fullName3": } |
我很少使用这种形式的
如果这是一种工厂创建决策过程,有更好的方法来实现。否则,我真的不明白你为什么要在一个类型上使用开关。
下面是一个关于Mark解决方案的小例子。我认为这是一种很好的工作方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 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 } |