僅初始化設定器僅在物件構造期間為屬性或索引器元素分配值。建構式的用例與 init 在物件構造期間設定值的用例有什么區別?
示例 1:
public class Person
{
private string _myName;
public Person(string myName)
{
_myName= myName;
}
public string Name => _myName;
}
示例 2:
public class Person
{
private string _myName;
public string Name
{
get { _myName; }
init { _myName= value; }
}
}
示例 3(忽略此示例,因為它與示例 2 相同):
public class Person
{
private string _myName;
public string Name
{
get => _myName;
init => _myName= value;
}
}
uj5u.com熱心網友回復:
在最大的不同:
- 建構式引數是強制性的,順序是從類本身定義的。
- 屬性初始值設定項是可選的,順序由呼叫者定義。
因此,如果您有強制引數和/或必須設定屬性的特定順序,請使用建構式,否則進行屬性初始化。
uj5u.com熱心網友回復:
下表描述了主要的差異和相似之處:(包括我的社論......)
| 建構式引數 | init 財產 |
|
|---|---|---|
| 自從 | C# 1.0 | C# 9.0 |
| 是必需的/有關于在場的硬保證 | 是的 | 不 |
| 自我記錄 | 從 C# 4.0 開始 | 是的 |
可以覆寫readonly欄位 |
是的 | 是的 |
| 適用于 | 必需和可選值 | 可選值 |
| 易于反射 | 只需使用 ConstructorInfo |
可怕 |
| 由MEDI支持 | 是的 | 不 |
休息時間 IDisposable |
不 | 是的 |
| 類知道初始化順序 | 是的 | 不 |
| 子類化時的人體工程學 | 乏味 | 體面的 |
的缺點init主要是從 C# 的物件初始值設定項運算式的缺點繼承而來的,這些缺點仍然存在許多問題(在腳注中)。
至于什么時候應該和不應該:
- 不要
init對必需值使用屬性 - 而是使用建構式引數。 - 務必將
init屬性用于非必要、非必需或其他可選值,這些值在通過單個屬性設定時不會使物件的狀態無效。
- 總之,
init性能使其稍微容易在穩定的型別初始化不必要的性能-但是他們也更容易搬起石頭砸自己的腳,如果你使用init的需要成員,而不是使用建構式的引數,尤其是C#8.0可空,參比型別。 - 在指導方面:
- 如果您
class不是不可變的,或者至少不在某些屬性上使用不可變語意,那么您不需要init在這些屬性上使用。- 但是,我想不出 a 中
init屬性的良好用例struct。
- 但是,我想不出 a 中
- 在我看來(其他人不共享),我建議您考慮可選(也可以為空)建構式引數或完全不同的建構式多載而不是
init屬性,因為我認為它們存在問題并且缺乏任何真正的優勢。
- 如果您
腳注:由init屬性繼承的 C# 物件初始值設定項語法的問題:
- 中斷除錯:即使在 C# 9 中,如果初始化程式的任何行拋出例外,則例外
StackTrace將與new陳述句位于同一行,而不是導致例外的子運算式的行。 - 符
IDisposable:如果一個屬性制定者(或初始化表達)拋出例外,并且如果型別工具IDisposable然后將新創建的實體將不會被設定-的,即使在構造完成(和物件被完全初始化只要CLR是擔心的)。
uj5u.com熱心網友回復:
這個想法是允許只讀屬性,您知道這些屬性僅在物件初始化期間具有寫入值,但在初始化之后無法寫入該值。
如果您定義了一個set方法而不是init,則可以在物件的生命周期內的任何時間寫入該值。
這允許您初始化屬性而不必將其作為引數直接傳遞給建構式。
例如:
class A
{
public int X { get; init;}
}
允許這樣做:
A a = new A()
{
X = 3,
};
并X在此之后嘗試寫入,將無法編譯:
a.X = 5;
給出編譯錯誤:
CS8852 Init-only property or indexer 'A.X' can only be assigned in an object initializer, or on 'this' or 'base' in an instance constructor or an 'init' accessor.
如果您不使用init,set而是使用,則可以隨時寫入您的物件。
如果你定義了一個沒有init方法的只讀屬性,你仍然可以在建構式中初始化該屬性,但是你必須向建構式傳遞一個引數。因此,使用的init決定更多地取決于您的代碼樣式以及您在哪里保存已初始化欄位的引數,以及您是否更愿意將其傳遞給建構式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/363627.html
標籤:C#
上一篇:C#-多個錯誤
