數據傳輸對象的兩個最佳選擇通常應該是一個深不可變的類對象,或者是一個具有適合用作數據傳輸對象的類型的暴露結構的結構。其他類型的結構有時也可以使用,但暴露域結構是迄今爲止最簡單的,簡單性是一個很大的優點。
的概念,可變的結構是邪惡的歷史可以追溯到一些早期的C#編譯器,其在
SomeReadonlyStruct.SomeProperty = 5;
會被編譯器默默轉換成:
var temp = SomeReadonlyStruct;
temp.SomeProperty = 5;
只讀屬性背後隱藏結構域是爲了確保前面的陳述會拒絕編譯而不是產生破損的代碼。由於較新的編譯器將拒絕改變只讀結構的可寫字段,所以不再需要將字段換成只讀屬性。
與其他類型的數據傳輸對象相比,帶有外露字段的結構具有巨大的優勢:每個結構具有適合於數據傳輸的類型的暴露字段,除了可能的構造函數外,沒有其他成員具有相同的行爲方式,沒有驚喜。有人從未使用結構可能會對他們不像類的行爲感到有點驚訝,但是理解這些結構作品如何理解它們是如何工作的人。
考慮下面的代碼:
customerPhone = someDataSource.GetPhoneNumber(customerID);
customerPhone.Extention = "5309"
有些人不喜歡的事實,如果customerPhone
是一個裸露的場結構,設置Extension
屬性將不會影響信息someDataSource
。儘管編寫結構體字段不會更新其他任何東西,但如果customerPhone
是可變類類型,情況會好得多。任何明白customerPhone
是暴露字段結構類型的人都知道,對其成員的更改不會影響其他任何內容。相比之下,如果customerPhone
是可變級類型,則上述代碼可能會通過更改與該customerID
相關聯的電話號碼來更新someDataSource
。或者它可能不會。或者,如果一個電話號碼與兩個customerID
值相關聯,則上面的代碼可能會更改它們兩個。爲確定上述代碼可能產生的影響和副作用,可能需要研究的代碼量相當大。更糟的是,可能很難確定一個人沒有遺漏任何東西。
確實有一些地方傳遞類對象引用可能比傳遞結構更有效。也有少數情況下,可變類對象可以成爲類中有用的數據持有者。然而,一些通用的包裝器可以將一個結構包裝在一個可變或不可變的類中,並且在這些類型的類之間交換信息。
interface IReadableHolder<T> { T Value {get;} }
class MutableHolder<T> : IReadableHolder<T>
{
public T Value;
IReadableHolder.Value {get {return Value;} }
public MutableHolder(T newValue) { Value = newValue; }
public MutableHolder(IReadableHolder<T> it) { Value = it.Value; }
}
class ImmutableHolder<T> : IReadableHolder<T>
{
T _Value;
public Value {get {return _Value;} }
public ImmutableHolder(T newValue) { _Value = newValue; }
}
如果沒有可變結構,這樣的構造會更笨拙。
「class」(這是一個簡單的; p) –
感謝所有參與! –