c# – 值型別是否包含引用型別?
我明白,使用值型別超過引用型別的決定應該基於語義,而不是效能.我不明白為什麼價值型別可以合法地包含引用型別的成員?這是由於幾個原因:
對於一個,我們不應該構建一個要求建構函式的結構體.
public struct MyStruct { public Person p; // public Person p = new Person(); // error: cannot have instance field initializers in structs MyStruct(Person p) { p = new Person(); } }
二,由於價值型別語義:
MyStruct someVariable; someVariable.p.Age = 2; // NullReferenceException
編譯器不允許我在宣告中初始化Person.我必須把它移到建構函式,依靠呼叫者,或者期待一個NullReferenceException.這些情況都不理想.
.NET框架是否有值型別中的引用型別的例子?我們該怎麼做(如果有的話)?
值型別的例項不包含引用型別的例項.引用型別的物件位於託管堆上,值型別物件可能包含對該物件的引用.這樣的參考具有固定的大小.這是很常見的,例如每次在結構體中使用字串時.
但是,是的,您不能保證在struct中初始化引用型別的欄位,因為您無法定義一個無引數的建構函式(如果用除C#之外的語言定義它也不能保證被呼叫).
你說你應該“不建立一個需要一個建構函式的結構體”.我說不.因為值型別幾乎總是不可變的,所以你必須使用一個建構函式(很可能通過一個工廠到一個私有建構函式).否則它永遠不會有任何有趣的內容.
使用建構函式.建構函式很好.
如果您不想傳入Person的例項來初始化p,則可以通過屬性使用延遲初始化. (因為很明顯,公共場所p只是為了示範,對不對?)
public struct MyStruct { public MyStruct(Person p) { this.p = p; } private Person p; public Person Person { get { if (p == null) { p = new Person(…); // see comment below about struct immutability } return p; } } // ^ in most other cases, this would be a typical use case for Lazy<T>; //but due to structs' default constructor, we *always* need the null check. }
程式碼日誌版權宣告:
翻譯自:http://stackoverflow.com/questions/10415157/when-would-a-value-type-contain-a-reference-type