跳转至

Switch对于类型的判断

判断一个对象是否是某个类型,可以使用is关键字,会考虑到对象的继承,当子类 is 父类 时,返回的也是true,使用==时,则会严格判断类型是否一致,即使继承关系也会返回false

switch关于类型判断的用法:

1、 只关心类型(使用了弃元,应该也是考虑到了继承来着)

public class Animal { }
public class Dog : Animal { }
public class Cat : Animal { }

switch (animal)
        {
            case null:
                Console.WriteLine("动物为 null");
                break;
            case Dog _:  // 匹配 Dog 类型(忽略实例本身,只关心类型)
                Console.WriteLine("这是一只狗");
                break;
            case Cat _:  // 匹配 Cat 类型
                Console.WriteLine("这是一只猫");
                break;
            default:
                Console.WriteLine("未知动物类型");
                break;
        }

_:是一个弃元(discard),表示 “我只关心类型是否匹配,不需要使用这个实例的值”。

2、 不考虑继承

 switch (obj.GetType())
    {
        case Type t when t == typeof(int):
            Console.WriteLine("这是 int 类型");
            break;
        case Type t when t == typeof(string):
            Console.WriteLine("这是 string 类型");
            break;
        case Type t when t == typeof(Dog):
            Console.WriteLine("这是 Dog 类型");
            break;
        default:
            Console.WriteLine("未知类型");
            break;
    }

when后面是判断条件,可以用==要求是严格的类型,即不考虑继承;也可以使用is考虑到具体的类型

3、 结合变量使用(需要访问实例成员时)

switch (obj)
{
    case int num:
        Console.WriteLine($"int 值为:{num}"); // 直接使用 num 变量
        break;
    case string str:
        Console.WriteLine($"string 长度:{str.Length}"); // 访问字符串长度
        break;
    case Dog dog:
        Console.WriteLine($"狗的名字:{dog.Name}"); // 访问 Dog 类的属性
        break;
    default:
        Console.WriteLine("未知类型");
        break;
}

4、 C# 8.0+ 开关表达式(Switch Expression,更简洁)

string result = obj switch
{
    int _ => "这是 int 类型",
    string _ => "这是 string 类型",
    Dog _ => "这是 Dog 类型",
    _ => "未知类型" // _ 表示默认情况
};
Console.WriteLine(result);

switch表达式返回一个值,因此需要使用变量来接收返回值。

特殊用法

匹配类型时可直接声明变量,用于访问实例的属性或方法:

public class Person { public int Age; }

// 根据年龄范围返回描述
string GetAgeGroup(Person person) => person switch
{
    { age: < 18 } => "未成年人",  // 属性模式:年龄小于18
    { age: >= 18 and <= 60 } => "成年人",  // 范围和逻辑运算
    { age: > 60 } => "老年人",
    null => "无此人",
    _ => "年龄未知"
};

多条件组合(使用 and/or 逻辑)

// 判断数字是否在指定范围
string CheckNumber(int num) => num switch
{
    < 0 => "负数",
    0 => "零",
    > 0 and <= 100 => "正数(1-100)",
    > 100 => "正数(>100)",
    _ => "无效数字"
};

元组模式(多值匹配)

// 根据坐标判断象限
string GetQuadrant((int x, int y) point) => point switch
{
    ( > 0, > 0 ) => "第一象限",
    ( < 0, > 0 ) => "第二象限",
    ( < 0, < 0 ) => "第三象限",
    ( > 0, < 0 ) => "第四象限",
    ( 0, 0 ) => "原点",
    ( 0, _ ) => "Y轴",
    ( _, 0 ) => "X轴",
    _ => "未知"
};

不想要返回值

object obj = "test";

// 开关表达式返回 object 类型,用 _ 接收(忽略结果)
_ = obj switch
{
    int num => Console.WriteLine($"整数:{num}"),
    string str => Console.WriteLine($"字符串:{str}"),
    _ => Console.WriteLine("未知类型")
};

5、 结合 nameof 动态获取类型名(通用写法)

switch (obj)
{
    case int _:
        Console.WriteLine($"这是 {nameof(Int32)} 类型"); // int 实际是 Int32 的别名
        break;
    case string _:
        Console.WriteLine($"这是 {nameof(String)} 类型");
        break;
    case Dog _:
        Console.WriteLine($"这是 {nameof(Dog)} 类型");
        break;
    default:
        Console.WriteLine($"未知类型:{obj?.GetType().Name ?? "null"}");
        break;
}