C#开启类型

时间:2010-12-18 14:32:34

标签: c#

  

可能重复:
  C# - Is there a better alternative than this to 'switch on type'?

C#不支持切换对象的类型。模拟这个的最佳模式是什么:

switch (typeof(MyObj))
    case Type1:
    case Type2:
    case Type3:

谢谢!

5 个答案:

答案 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
}