簡體   English   中英

為什么我不能使用as關鍵字作為結構?

[英]Why can't I use the as keyword for a struct?

我定義了以下結構:

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的結果是該類型的空值。

但是,您可以使用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值轉換為引用類型的變量(或可空值類型),但不能轉換為非可空值類型。

struct是值類型,因此不能與as運算符一起使用。 如果轉換失敗, as運算符必須能夠賦值null。 這僅適用於引用類型或可空值類型。

有幾種方法可以解決這個問題,但最好的辦法是將Call類型從結構更改為類。 這實質上會將您的類型從值類型更改為引用類型,這允許as運算符在轉換失敗時指定null值。

有關值類型與引用類型的更多信息, 是一篇不錯的文章。 另外,看看MSDN:

來自C#規范

§7.10.11as運算符用於將值顯式轉換為給定的引用類型可空類型 與強制轉換表達式(第7.7.6節)不同,as運算符從不拋出異常。 相反,如果無法指示轉換,則結果值為

引用和可空類型可以為null。 Stucts是值類型,因此它們不能為null。

Call? call = line.Tag as Call?;

這是C#的限制。 如果類型是引用類型,那么如果轉換失敗,它將只返回'null',但由於它是一個值類型,它不知道在轉換失敗時返回什么。

你必須將你的使用替換成兩個:'是'和'as'

if (line.Tag is Call) {
  call = (Call)line.Tag;
} else {
  // Do whatever you would do if as returned null.
}

意義是什么 - 如上所述,結構是價值類型。

我該如何解決 - 將其更改為

Call call = line.Tag;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM