不明确的行为,如果我声明类型:
struct Token
{
public static implicit operator int(Token x)
{
return 0;
}
public static implicit operator string(Token x)
{
return "";
}
}
Run Code Online (Sandbox Code Playgroud)
我们有两个隐式转换.如果我使用工作文件
var t = new Token();
if (t == "123")
{
}
Run Code Online (Sandbox Code Playgroud)
CS0151:开关表达式或大小写标签必须是bool,char,string,integral,enum或相应的可空类型
如果我使用:
switch (t)
{
case "123" :
{
break;
}
}
Run Code Online (Sandbox Code Playgroud)
但如果我删除int隐式转换,则错误消失.
struct Token
{
public static implicit operator string(Token x)
{
return "";
}
}
Run Code Online (Sandbox Code Playgroud)
它是编译器中的错误还是正确的行为?
编译器的混乱似乎是可以理解的.该switch声明可以同时运行int和string.您传递的内容Token包含对两者的隐式转换.编译器应该选择哪一个?它无法知道哪个是首选.隐式构造函数没有优先级.
在这种if情况下,很明显你要比较一个字符串,以便使用转换.但是转换是模棱两可的.错误并不完全清楚,但我假设,不知道选择哪个转换,它不选择,尝试将Token实例本身放在交换机中,从而显示此错误.
这是正确的行为.从规范,8.7.2开关语句:
从switch表达式的类型到以下可能的控制类型之一,必须存在一个用户定义的隐式转换(第6.4节):sbyte,byte,short,ushort,int,uint,long,ulong,char,string.如果不存在此类隐式转换,或者存在多个此类隐式转换,则会发生编译时错误.
我们还可以看到实现规范的(下一版本)编译器源代码Conversions.UserDefinedImplicitConversions.
请注意,我删除了一些代码和注释,这只是为了得到一般的想法:
UserDefinedConversionResult? exactConversionResult = null;
foreach (UserDefinedConversionAnalysis analysis in u)
{
TypeSymbol tx = analysis.ToType;
if (tx.IsValidSwitchGoverningType(isTargetTypeOfUserDefinedOp: true))
{
if (!exactConversionResult.HasValue)
{
exactConversionResult = UserDefinedConversionResult.Valid(u, best.Value);
continue;
}
return UserDefinedConversionResult.Ambiguous(u);
}
}
// If there exists such unique TX in suitableTypes, then that operator is the
// resultant user defined conversion and TX is the resultant switch governing type.
// Otherwise we either have ambiguity or no applicable operators.
return exactConversionResult.HasValue ?
exactConversionResult.Value :
UserDefinedConversionResult.NoApplicableOperators(u);
Run Code Online (Sandbox Code Playgroud)
基本上,代码会迭代隐式转换,并将它找到的第一个转换保持为可以出现的类型switch.如果找到它返回的另一种类型Ambiguous.如果它只找到一种类型,则返回它.
同样,这是代码的简短版本,完整代码处理更多案例和树皮兼容性.
| 归档时间: |
|
| 查看次数: |
283 次 |
| 最近记录: |