为什么我不能对结构使用 as 关键字?
-
25-09-2019 - |
题
我定义了以下结构:
public struct Call
{
public SourceFile caller;
public SourceFile callee;
public Call(SourceFile caller, SourceFile callee)
{
this.caller = caller;
this.callee = callee;
}
}
后来,我将它分配给另一个对象的 Tag 属性:
line.Tag = new Call(sf1, sf2);
但是当我尝试像这样检索 Tag 属性时,
Call call = line.Tag as Call;
Visual Studio 给出以下编译时错误:
运算符必须在参考类型或无效类型中使用
那是什么意思?我该如何解决它?
其他提示
一些现有的答案不是 相当 正确的。你不能使用 不可为空 类型与 as
, ,因为结果 as
如果第一个操作数实际上不是适当的类型,则为该类型的 null 值。
然而,你 能 使用 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
那么你 可以 使用:
Call? call = line.Tag as Call?;
然后您可以将其用作:
if (call != null)
{
// Do stuff with call.Value
}
但有两个警告:
- 根据我的经验,这比仅仅使用慢
is
随后是演员阵容 - 你应该认真地重新考虑一下你现在的情况
Call
类型:- 它暴露了公共字段,这通常是封装很差的
- 这是一个可变值类型,这几乎肯定是一个错误
我强烈建议你把它变成一个类 - 到那时这个问题就消失了。
另一个想法:如果标签应该 总是 成为一个 Call
, ,那么最好将其投射:
Call call = (Call) line.Tag;
这样,如果数据与您的期望不符(即有一些错误,例如 Tag
不是一个 Call
)然后你就可以尽早发现它,而不是在你可能完成其他一些工作之后。请注意,此转换的行为会有所不同,具体取决于是否 Call
是一个结构体或一个类,如果 Tag
为 null - 您可以将 null 值转换为引用类型(或可为 null 值类型)的变量,但不能转换为不可为 null 值类型。
从C#规格
§7.10.11as运算符被用来 明确将值转换为一个给定的 的引用类型或的空类型即可。与强制转换表达式 (§7.7.6),as运算符从不抛出 一个例外。相反,如果 指示的转换是不可能的, 所得到的值是<强>空强>
参考和空类型可以为空。 Stucts是值类型,所以他们不能为空。
Call? call = line.Tag as Call?;
它的C#的限制。如果类型是引用类型,那么如果转换失败,它只会返回“空”,但因为它是值类型,不知道什么时候转换失败什么返回。
您必须更换您的使用视为有两个:“是”和“为”
if (line.Tag is Call) {
call = (Call)line.Tag;
} else {
// Do whatever you would do if as returned null.
}
的含义是什么 - 。如所述的,结构是值类型
我怎样才能解决这个问题 - 将其更改为
Call call = line.Tag;