C#8.0 switch语句模式匹配局部变量使用报错问题咨询
你在把旧的switch语句转成C#8.0的模式匹配写法时,主要是对switch表达式和模式匹配switch语句的语法规则理解有偏差,咱们逐个拆解问题:
写法1的问题:switch表达式语法错误+缺少默认分支
C#8.0的switch表达式是一个可返回值的表达式,正确语法是把switch表达式直接放在赋值运算符右侧,不需要在switch前额外加符号。另外,switch表达式要求必须覆盖所有可能的输入情况——要么列出所有潜在类型,要么提供default分支,否则编译器会因“未覆盖所有情况”报错。
你的写法1里propertyInfo = switch (...)属于语法错误,正确的赋值方式是把propertySelectorExpression.Body switch { ... }作为整体赋值给变量,同时必须补充默认分支处理其他类型。
写法2的问题:switch语句的模式匹配语法错误
如果想用带模式匹配的switch语句,不能直接把MemberExpression me => ...放在switch块里。正确语法是保留case关键字,跟上匹配模式,再用=>写表达式形式的分支体(这是C#8.0给switch语句新增的特性)。
正确写法1:使用switch表达式
PropertyInfo propertyInfo = propertySelectorExpression.Body switch { MemberExpression me => me.Member as PropertyInfo, UnaryExpression ue => (ue.Operand as MemberExpression)?.Member as PropertyInfo, _ => null // 通配符模式作为默认分支,覆盖所有其他类型 };
这里的_是通配符模式,用来处理所有未明确列出的情况,确保满足switch表达式的完整性要求。
正确写法2:使用带模式匹配的switch语句
PropertyInfo propertyInfo = null; switch (propertySelectorExpression.Body) { case MemberExpression me => propertyInfo = me.Member as PropertyInfo, case UnaryExpression ue => propertyInfo = (ue.Operand as MemberExpression)?.Member as PropertyInfo, case _ => propertyInfo = null; // 可选,但建议添加以覆盖所有潜在情况 }
注意每个分支前都保留了case关键字,这是C#8.0 switch语句支持的表达式式分支写法,不需要手动写break,分支体直接是一个赋值表达式。
额外补充:如果propertySelectorExpression.Body只会是MemberExpression或UnaryExpression两种类型,你也可以用更严谨的is模式匹配来替代as,比如把me.Member as PropertyInfo改成me.Member is PropertyInfo pi ? pi : null,不过保持和原逻辑一致的写法也完全没问题。
内容的提问来源于stack exchange,提问作者Yves Schelpe

