I defined the following struct:
我定义了以下结构:
public struct Call
{
public SourceFile caller;
public SourceFile callee;
public Call(SourceFile caller, SourceFile callee)
{
this.caller = caller;
this.callee = callee;
}
}
Later, I assign it to the Tag property of another object:
稍后,我将其分配给另一个对象的Tag属性:
line.Tag = new Call(sf1, sf2);
But when I try to retrieve the Tag property like so,
但是当我尝试像这样检索Tag属性时,
Call call = line.Tag as Call;
Visual Studio gives the following compile-time error:
Visual Studio提供以下编译时错误:
The operator as must be used within a reference type or nullable type
必须在引用类型或可空类型中使用运算符
What is the meaning of that? And how can I solve it?
那是什么意思?我该如何解决?
6 个解决方案
#1
31
A struct is a value type, so it cannot be used with the as
operator. The as
operator must be able to assign a value of null if the cast fails. This is only possible with a reference type or a nullable value type.
struct是值类型,因此不能与as运算符一起使用。如果转换失败,as运算符必须能够赋值null。这仅适用于引用类型或可空值类型。
There are a couple ways to solve this, but your best bet is to change your Call
type from a struct to a class. This will essentially change your type from a value type to a reference type, which allows the as
operator to assign a value of null if the cast fails.
有几种方法可以解决这个问题,但最好的办法是将Call类型从结构更改为类。这实际上会将您的类型从值类型更改为引用类型,这允许as运算符在转换失败时指定null值。
For more information on value types vs. reference types, this is a decent article. Also, have a look on MSDN:
有关值类型与引用类型的更多信息,这是一篇不错的文章。另外,看看MSDN:
- value types
- 价值类型
- reference types
- 参考类型
- as-operator
- 作为运营商
- nullable types.
- 可空类型。
#2
32
Some of the existing answers aren't quite right. You can't use non-nullable types with as
, because the result of as
is the null value of the type if the first operand isn't actually of an appropriate type.
一些现有的答案并不完全正确。您不能将非可空类型与as一起使用,因为如果第一个操作数实际上不是合适的类型,则as的结果是该类型的空值。
However, you can use as
with value types... if they're nullable:
但是,您可以使用值类型...如果它们可以为空:
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
So you could use:
所以你可以使用:
Call? call = line.Tag as Call?;
Then you can use it as:
然后你可以用它作为:
if (call != null)
{
// Do stuff with call.Value
}
Two caveats though:
但有两点需要注意:
- In my experience this is slower than just using
is
followed by a cast - 根据我的经验,这比使用后跟一个演员要慢
- You should seriously reconsider your current
Call
type:- It's exposing public fields, which is generally poor encapsulation
- 它暴露了公共领域,这通常是很糟糕的封装
- It's a mutable value type, which is almost certainly a mistake
- 这是一个可变的值类型,几乎肯定是一个错误
- 你应该认真重新考虑你当前的Call类型:它暴露了公共字段,这通常是不好的封装它是一个可变的值类型,这几乎肯定是一个错误
I would strongly suggest you make it a class instead - at which point this problem goes away anyway.
我强烈建议你把它变成一个班级 - 无论如何这个问题都会消失。
Another thought: if the tag should always be a Call
, then it's better to cast it:
另一个想法:如果标签应该始终是一个Call,那么最好将其转换为:
Call call = (Call) line.Tag;
That way, if the data doesn't match your expectation (i.e. there's some bug such that the Tag
isn't a Call
) then you get to find out about it early, rather than after you've potentially done some other work. Note that this cast will behave differently depending on whether Call
is a struct or a class, if Tag
is null - you can cast a null value to a variable of a reference type (or a nullable value type), but not to a non-nullable value type.
这样,如果数据与您的期望不符(即,有一些错误,使得标签不是一个呼叫),那么您可以尽早找到它,而不是在您可能完成其他工作之后。请注意,根据Call是一个结构还是一个类,如果Tag为null,这个转换将表现不同 - 您可以将null值转换为引用类型的变量(或可空值类型),但不能转换为非可空值类型。
#3
12
From the C# Spec
来自C#规范
§7.10.11 The as operator is used to explicitly convert a value to a given reference type or nullable type. Unlike a cast expression (§7.7.6), the as operator never throws an exception. Instead, if the indicated conversion is not possible, the resulting value is null.
§7.10.11as运算符用于将值显式转换为给定的引用类型或可空类型。与强制转换表达式(第7.7.6节)不同,as运算符从不抛出异常。相反,如果无法指示转换,则结果值为空。
References and nullable types can be null. Stucts are value types so they can't be null.
引用和可空类型可以为null。 Stucts是值类型,因此它们不能为null。
#4
1
Call? call = line.Tag as Call?;
#5
0
It's a limitation of C#. If the type were a reference type, then if the cast failed it would simply return 'null', but since it's a value type, it doesn't know what to return when the cast fails.
这是C#的限制。如果类型是引用类型,那么如果转换失败,它将只返回'null',但由于它是一个值类型,它不知道在转换失败时返回什么。
You must replace your use of as with two: 'is' and 'as'
您必须将以下两种用法替换为:'is'和'as'
if (line.Tag is Call) {
call = (Call)line.Tag;
} else {
// Do whatever you would do if as returned null.
}
#6
-1
What is the meaning - As stated, structures are value types.
意义是什么 - 如上所述,结构是价值类型。
How can I solve it - Change it to
我怎样才能解决它 - 改成它
Call call = line.Tag;
#1
31
A struct is a value type, so it cannot be used with the as
operator. The as
operator must be able to assign a value of null if the cast fails. This is only possible with a reference type or a nullable value type.
struct是值类型,因此不能与as运算符一起使用。如果转换失败,as运算符必须能够赋值null。这仅适用于引用类型或可空值类型。
There are a couple ways to solve this, but your best bet is to change your Call
type from a struct to a class. This will essentially change your type from a value type to a reference type, which allows the as
operator to assign a value of null if the cast fails.
有几种方法可以解决这个问题,但最好的办法是将Call类型从结构更改为类。这实际上会将您的类型从值类型更改为引用类型,这允许as运算符在转换失败时指定null值。
For more information on value types vs. reference types, this is a decent article. Also, have a look on MSDN:
有关值类型与引用类型的更多信息,这是一篇不错的文章。另外,看看MSDN:
- value types
- 价值类型
- reference types
- 参考类型
- as-operator
- 作为运营商
- nullable types.
- 可空类型。
#2
32
Some of the existing answers aren't quite right. You can't use non-nullable types with as
, because the result of as
is the null value of the type if the first operand isn't actually of an appropriate type.
一些现有的答案并不完全正确。您不能将非可空类型与as一起使用,因为如果第一个操作数实际上不是合适的类型,则as的结果是该类型的空值。
However, you can use as
with value types... if they're nullable:
但是,您可以使用值类型...如果它们可以为空:
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
So you could use:
所以你可以使用:
Call? call = line.Tag as Call?;
Then you can use it as:
然后你可以用它作为:
if (call != null)
{
// Do stuff with call.Value
}
Two caveats though:
但有两点需要注意:
- In my experience this is slower than just using
is
followed by a cast - 根据我的经验,这比使用后跟一个演员要慢
- You should seriously reconsider your current
Call
type:- It's exposing public fields, which is generally poor encapsulation
- 它暴露了公共领域,这通常是很糟糕的封装
- It's a mutable value type, which is almost certainly a mistake
- 这是一个可变的值类型,几乎肯定是一个错误
- 你应该认真重新考虑你当前的Call类型:它暴露了公共字段,这通常是不好的封装它是一个可变的值类型,这几乎肯定是一个错误
I would strongly suggest you make it a class instead - at which point this problem goes away anyway.
我强烈建议你把它变成一个班级 - 无论如何这个问题都会消失。
Another thought: if the tag should always be a Call
, then it's better to cast it:
另一个想法:如果标签应该始终是一个Call,那么最好将其转换为:
Call call = (Call) line.Tag;
That way, if the data doesn't match your expectation (i.e. there's some bug such that the Tag
isn't a Call
) then you get to find out about it early, rather than after you've potentially done some other work. Note that this cast will behave differently depending on whether Call
is a struct or a class, if Tag
is null - you can cast a null value to a variable of a reference type (or a nullable value type), but not to a non-nullable value type.
这样,如果数据与您的期望不符(即,有一些错误,使得标签不是一个呼叫),那么您可以尽早找到它,而不是在您可能完成其他工作之后。请注意,根据Call是一个结构还是一个类,如果Tag为null,这个转换将表现不同 - 您可以将null值转换为引用类型的变量(或可空值类型),但不能转换为非可空值类型。
#3
12
From the C# Spec
来自C#规范
§7.10.11 The as operator is used to explicitly convert a value to a given reference type or nullable type. Unlike a cast expression (§7.7.6), the as operator never throws an exception. Instead, if the indicated conversion is not possible, the resulting value is null.
§7.10.11as运算符用于将值显式转换为给定的引用类型或可空类型。与强制转换表达式(第7.7.6节)不同,as运算符从不抛出异常。相反,如果无法指示转换,则结果值为空。
References and nullable types can be null. Stucts are value types so they can't be null.
引用和可空类型可以为null。 Stucts是值类型,因此它们不能为null。
#4
1
Call? call = line.Tag as Call?;
#5
0
It's a limitation of C#. If the type were a reference type, then if the cast failed it would simply return 'null', but since it's a value type, it doesn't know what to return when the cast fails.
这是C#的限制。如果类型是引用类型,那么如果转换失败,它将只返回'null',但由于它是一个值类型,它不知道在转换失败时返回什么。
You must replace your use of as with two: 'is' and 'as'
您必须将以下两种用法替换为:'is'和'as'
if (line.Tag is Call) {
call = (Call)line.Tag;
} else {
// Do whatever you would do if as returned null.
}
#6
-1
What is the meaning - As stated, structures are value types.
意义是什么 - 如上所述,结构是价值类型。
How can I solve it - Change it to
我怎样才能解决它 - 改成它
Call call = line.Tag;