mic*_*hut 2 c# casting nullable implicit-cast
我已经定义了自定义值类型MyCustomValueType,隐式转换运算符从long到MyCustomValueType.
public struct MyCustomValueType
{
private readonly long number;
public MyCustomValueType(long? number)
{
this.number = number.GetValueOrDefault(0);
}
public static implicit operator MyCustomValueType(long number)
{
return new MyCustomValueType(number);
}
}
Run Code Online (Sandbox Code Playgroud)
然后编译器允许我执行以下操作:
// ...
long? value = null;
MyCustomValueType myCustomValueType = (MyCustomValueType)value;
Console.WriteLine(myCustomValueType);
Run Code Online (Sandbox Code Playgroud)
在引擎盖下,编译器将使用强制转换的语句转换为:
MyCustomValueType myCustomValueType = ((long?)null).Value;
Run Code Online (Sandbox Code Playgroud)
我想知道(或更好地说WHY)是怎么发生的?为什么编译器甚至允许显式转换没有定义任何人.编译器适用的规则是什么?
我可能还应该提到,当MyCustomValueType仅定义用于强制转换的显式运算符时,也可以进行此类强制转换,例如:
public static explicit operator MyCustomValueType(long number)
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,我以某种方式接受编译器的作用并理解它.隐式运算符的情况确实令人困惑.有人可以解释一下吗?
为什么编译器甚至允许显式转换没有定义任何人.编译器适用的规则是什么?
它适用于C#规范第6.4.2节中定义的提升转换:
鉴于从非空值类型转换一个用于定义转换运算符
S
到一个非空值类型T
,一个提升转换运算符存在从转换S?
到T?
.此提升转换运算符执行从解包S?
到S
,随后从用户定义的转换S
,以T
从,随后缠绕T
到T?
,不同的是一个空值S?
直接转换到一个空值T?
.
所以你可以把它想象成:
long? value = null;
long tmp1 = (long) value; // Unwrapping
MyCustomValueType tmp2 = tmp1; // User-defined conversion
MyCustomValueType? tmp3 = tmp2; // Wrapping
MyCustomValueType myCustomValueType = (MyCustomValueType) tmp3; // Unwrapping
Run Code Online (Sandbox Code Playgroud)
我不认为这是特别令人惊讶的,说实话 - 特别是,如果你明白当声明的转换运算符是显式的时候某些东西是可行的,那么当声明的转换运算符是隐含的时候,值得期望相同的用法是可行的..(当然,不一定是反过来.)
归档时间: |
|
查看次数: |
213 次 |
最近记录: |