23 .net c# type-systems casting as-operator
我定义了以下结构:
public struct Call
{
public SourceFile caller;
public SourceFile callee;
public Call(SourceFile caller, SourceFile callee)
{
this.caller = caller;
this.callee = callee;
}
}
Run Code Online (Sandbox Code Playgroud)
稍后,我将它分配给另一个对象的Tag属性:
line.Tag = new Call(sf1, sf2);
Run Code Online (Sandbox Code Playgroud)
但是当我尝试像这样检索Tag属性时,
Call call = line.Tag as Call;
Run Code Online (Sandbox Code Playgroud)
Visual Studio提供以下编译时错误:
必须在引用类型或可空类型中使用运算符
那是什么意思?我该如何解决?
Jon*_*eet 34
一些现有的答案并不完全正确.您不能使用非可空类型as
,因为as
如果第一个操作数实际上不是合适的类型,则结果为该类型的空值.
但是,您可以使用as
值类型...如果它们可以为空:
int a = 10;
object o = a;
int? x = o as int?; // x is a Nullable<int> with value 10
long? y = o as long?; // y is a Nullable<long> with the null value
Run Code Online (Sandbox Code Playgroud)
所以你可以使用:
Call? call = line.Tag as Call?;
Run Code Online (Sandbox Code Playgroud)
然后你可以用它作为:
if (call != null)
{
// Do stuff with call.Value
}
Run Code Online (Sandbox Code Playgroud)
但有两点需要注意:
is
后续演员要慢Call
类型:
我强烈建议你把它变成一个班级 - 无论如何这个问题都会消失.
另一个想法:如果标签应该始终是a Call
,那么最好将它投射:
Call call = (Call) line.Tag;
Run Code Online (Sandbox Code Playgroud)
这样,如果数据与您的期望不符(即有一些错误,使得Tag
它不是a Call
),那么您可以尽早找到它,而不是在您可能完成其他工作之后.请注意,此转换的行为将取决于Call
是结构还是类,如果Tag
为null ,则可以将null值转换为引用类型的变量(或可空值类型),但不能转换为非可空值类型.
Con*_*rix 12
来自C#规范
§7.10.11as运算符用于将值显式转换为给定的 引用类型或可空类型.与强制转换表达式(第7.7.6节)不同,as运算符从不抛出异常.相反,如果无法指示转换,则结果值为空.
引用和可空类型可以为null.Stucts是值类型,因此它们不能为null.