簡體   English   中英

屬性值賦值

[英]Property value assignment

我不明白為什么代碼的一塊是有效的,但不是后者

var e = new Exception()
{
    Data =
    {
        {"a","a"}
    }
};

這里的編譯時錯誤:

e.Data =
{
    {"a","a"}
};

Well Data屬性已被聲明只讀屬性:

public virtual System.Collections.IDictionary Data { get; }

這就是為什么你可以初始化它(即在構造函數中設置)

  // Create an instance, initialize `Data` with { "a", "a" }
  Exception e = new Exception() {
    Data = { { "a", "a" } }
  };

但你不能設置它:

 // Trying to set Data as { { "a", "a" } };
 e.Data = { { "a", "a" } }; // <- Compile time error here

錯誤 CS0200 無法將屬性或索引器“Exception.Data”分配給 - 它是只讀的(粗體是我的,Dmitry Bychenko)

請注意,您可以所需項目添加到Data中:

  Exception e = new Exception();

  // Add {"a", "a"} to existing Data
  e.Data.Add("a", "a"); 

另一個答案不是 100% 准確。 是的, Data是只讀屬性。 但是,只讀(即,僅 getter)屬性只能被賦予初始/默認值(在這種情況下,該值被分配給編譯器生成的支持字段),但不能被分配給; 時期。 不在 object 初始化程序中,不在構造函數中,也不在其他任何地方。

請注意,另一方面,可以在構造函數中分配只讀字段

為了分配給一個屬性,它必須有一個 setter(例如set;private set;等),如果您使用 C# 9.0 或更高版本,您可以使用僅 init 的 setter (即init; ) 這將允許您分配給 object 初始化程序中的屬性,但之后不能。

只要該屬性沒有設置器,就永遠無法直接更改其值。 為了證明這一點,請嘗試在 object 初始化程序中將Data設置為null

var e = new Exception()
{
    Data = null  // Nope, compiler won't allow it because Data is readonly
};

那么,為什么它在第一個塊中起作用?

那是因為您正在使用Collection Initializer初始化Data 當你這樣做時,編譯器實際上並沒有為屬性賦值。 相反,它調用Add()方法。 您可以在此處親自查看。 第一個(即工作)塊由編譯器翻譯成:

Exception e = new Exception();
e.Data.Add("a", "a"); // <-- Ah! `Data` was never assigned to.

..順便說一下,通常會拋出 NullReferenceException (因為我們在應該為 null 的屬性上調用Add()方法)。 但是,如果您查看Exception.Data源代碼,您會發現它的支持字段始終在 getter 中初始化,因此它永遠不會是 null:

public virtual IDictionary Data { 
    [System.Security.SecuritySafeCritical]  // auto-generated
    get {
        if (_data == null)
            if (IsImmutableAgileException(this))
                _data = new EmptyReadOnlyDictionaryInternal();
            else
                _data = new ListDictionaryInternal();
        
        return _data;
    }
}

您不能分配數據,因為 Data 是字典。 如果新字典 object 有一個 setter,則可以分配它,但 Data 只有一個 getter,它在初始化時創建為空集合

public class ABC
{
 public virtual System.Collections.IDictionary Data { get; } =  new Dictionary<object,object> ();
}

你只能通過一些數據來初始化它,就像使用 Collection Initializer 的任何其他集合一樣

    var abc = new ABC()
    {
        Data = {
        {"a","a"}
       }
    };

或通過兩種常用方式添加新項目,就像您使用任何其他字典一樣

    abc.Data["c"] = "c";
    //or 
    abc.Data.Add("d", "d");
}

暫無
暫無

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

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