[英]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.