C# 根据类型进行切换

11 浏览
0 Comments

C# 根据类型进行切换

C#不支持根据对象类型进行switch语句判断。在模拟此功能时,最佳模式是:

0
0 Comments

C#中的switch语句只能对整数类型或枚举类型进行匹配,无法直接对类型进行匹配。但是,有时候我们需要根据不同的类型执行不同的操作。下面是一个解决这个问题的方法,以及一些相关的讨论。

一种解决方法是使用字典来存储不同类型对应的操作。可以将类型作为字典的键,将对应的操作作为值。然后,在需要执行操作的地方,根据类型从字典中取出对应的操作并执行。以下是一个示例代码:

var actions = new Dictionary {
    { typeof(Type1), () => ... },
    { typeof(Type2), () => ... },
    { typeof(Type3), () => ... },
};
actions[typeof(MyType)]();

这种方法的好处是简单直接,而且效率高。但是,它有一些限制。首先,它不能处理子类的情况。例如,如果MyType是object的子类,那么`typeof(object) != typeof(MyType)`,因此无法通过类型直接匹配到MyType。其次,它不能实现case穿透和continue等复杂的控制流程。

针对这些限制,可以采用其他的解决方法。例如,可以在从字典中取出操作之前,先检查字典中是否包含该类型。可以使用`ContainsKey`方法进行检查。以下是一个示例代码:

if (actions.ContainsKey(typeof(MyType)))
    actions[typeof(MyType)]();

这样做的好处是可以避免出现类型不存在于字典中的情况,提高了代码的健壮性。

如果需要支持子类的情况,可以使用`IsAssignableFrom`方法来进行类型比较。以下是一个示例代码:

foreach (var kvp in actions)
{
    if (kvp.Key.IsAssignableFrom(typeof(MyType)))
    {
        kvp.Value();
        break;
    }
}

这样做的好处是可以支持子类的匹配,但是代码相对复杂。

除了以上的方法外,还可以根据具体需求编写自定义的`IEqualityComparer`来进行类型比较。但是需要注意的是,编写好的`GetHashCode`方法可能比较困难,同时需要注意比较的方向,以避免出现不一致的情况。

最后,需要注意的是,C#中已经有一些新的特性可以解决这个问题。可以参考相关的回答获取更多信息。

,C#中的switch语句无法直接对类型进行匹配,但是可以使用字典、ContainsKey、IsAssignableFrom等方法来实现对类型的匹配。根据具体的需求,选择合适的方法来解决问题。

0
0 Comments

C#中的switch语句可以用于根据不同的值执行不同的操作。然而,C#的switch语句不支持根据类型执行不同的操作。这就导致了在处理不同类型的对象时可能会出现问题。

为了解决这个问题,有两种常见的方法。第一种方法是使用类型字典来查找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");

在这个示例中,我们创建了一个TypeSwitch对象,并使用Case方法为不同的类型添加了lambda函数。然后,我们可以使用Switch方法来根据不同的值执行相应的操作。

除了使用类型字典,还可以使用模式匹配来解决这个问题。模式匹配可以根据类型和运行时检查的条件来执行操作。下面是一个使用模式匹配的示例代码:

var getRentPrice = new PatternMatcher()

.Case(bike => 100 + bike.Cylinders * 10)

.Case(30)

.Case(car => car.EngineType == EngineType.Diesel, car => 220 + car.Doors * 20)

.Case(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));

}

在这个示例中,我们创建了一个PatternMatcher对象,并使用Case方法为不同的类型添加了函数。函数的参数可以是类型本身或者是一个lambda表达式,用于检查对象的属性。然后,我们可以使用Match方法来根据不同的值执行相应的操作。

通过使用类型字典或模式匹配,我们可以在C#中实现根据类型执行不同操作的需求。这样可以提高代码的可读性和可维护性,并避免在处理不同类型的对象时出现问题。

0
0 Comments

C#中出现switch on type的问题是因为在旧版本中没有直接支持这种语法。解决这个问题的方法有几种:

1. 使用访问者模式(visitor pattern),但这可能会比较复杂,需要深入了解。

2. 使用LINQ来处理,可以参考链接http://community.bartdesmet.net/blogs/bart/archive/2008/03/30/a-functional-c-type-switch.aspx中的示例代码。

3. 使用if-then语句进行类型判断,但这种方法可能会显得繁琐和笨拙。示例代码如下:

// 繁琐
switch(MyObj.GetType().ToString()){
  case "Type1": etc
}
// 笨拙
if myObj is Type1 then
if myObj is Type2 then

然而,使用函数式的c-type switch存在一个问题,就是它没有像实际的switch-case语法一样获得预编译的速度。这可能会让程序员过度使用这种看起来像switch的类,误以为它具有相同的优势。实际上,这只是一个更昂贵的if-then-with-lambdas的包装器。

对于类型测试,我实际上更喜欢使用if-then,因为我不需要处理字符串。使用简单的if-then对比's solution: if (typeTests.Keys.Contains(TypeToTest)),你将得到与switch-case相当的性能(因为有哈希键),而且不容易出错,我个人而言更喜欢这种方法。

另外,如果你担心使用字符串作为类型名称可能导致重命名问题,可以使用nameof(Type1)代替字符串字面量。实际上,无论何时一个字符串真正代表了类型或属性的名称,都应该使用nameof(Type1)进行处理。

这些方法并不完全解决问题,因为它们都是围绕对象的类型进行判断,而不是直接对类型进行判断。然而,在C# 7.0中,可以使用模式匹配(pattern matching)来解决这个问题,示例代码如下:

switch (MyObj)
    case Type1 t1: 
    case Type2 t2:
    case Type3 t3:

这样就可以直接在类型实例上进行switch操作了。当然,使用重载方法也可以实现类似的效果,为每种需要处理的类型编写不同的重载方法。

希望这些解决方法能对你有所帮助!如果你想了解更多关于这个的问题,可以参考下面的链接:

- stackoverflow.com/a/299001

- stackoverflow.com/questions/44905

0