到目前为止,我一直认为,如果我检查参数是否“是”T,那么强制转换“as”T 应该是安全的。所以这总是会成功并且永远不会为空:
if (myParam is MyClass)
{
MyClass instance = myParam as MyClass;
}
Run Code Online (Sandbox Code Playgroud)
但是,编译器警告我右侧可能为空:
“CS8600:将 null 文字或可能的 null 值转换为不可为 null 的类型。”
这真的会发生吗?还是编译器根本没有得到前面的检查?如果它仍然可以为空,这怎么可能呢?
根据微软文档,这似乎不可能: https://learn.microsoft.com/en-au/dotnet/csharp/language-reference/operators/type-testing-and-cast
形式的表达
东方
其中 E 是返回值的表达式,T 是类型或类型参数的名称,产生与以下相同的结果
E 是 T 吗?(T)(E) : (T)空
注意:(我以一种相当复杂的方式将 myParam 作为泛型类中的参数;原则上,如果需要的话,只要付出一点努力,我就可以创建一个最小的示例,但到目前为止我很确定,不存在这种情况演员阵容可能会失败。)
这是安全的。编译器警告是由于可为空引用类型功能引起的。
在分析表达式是否可以为 null 时,C# 仅对您执行的 null 检查进行控制流分析,而不对您执行的类型检查进行控制流分析。例如,C#可以这样理解:
if (myParam != null) {
// C# understands that myParam is not null here
}
Run Code Online (Sandbox Code Playgroud)
但不是:
if (myParam is MyClass) {
// C# does not understand that myParam is of type MyClass here
}
Run Code Online (Sandbox Code Playgroud)
因此,C# 认为该表达式myParam as MyClass为“maybe null”。它发现您正在将其分配给一个不可为空的变量instance,因此会出现警告。请参阅此处以供参考。
在旧版本的 C# 中,可空引用类型不存在,因此不会出现任何警告。每个引用类型都可以为空。
您应该使用声明模式来检查类型。
if (myParam is MyClass instance) {
// use instance here...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
56 次 |
| 最近记录: |