[英]C#: How to set default value for a property in a partial class?
我對C#很新,所以請耐心等待......
我正在實現一個部分類,並希望添加兩個屬性,如下所示:
public partial class SomeModel
{
public bool IsSomething { get; set; }
public List<string> SomeList { get; set; }
... Additional methods using the above data members ...
}
我想初始化兩個數據成員: IsSomething
為True
, SomeList
為new List<string>()
。 通常我會在構造函數中執行它,但是因為它是一個部分類我不想觸及構造函數(我應該嗎?)。
實現這一目標的最佳方法是什么?
謝謝
PS我在ASP.NET MVC中工作,為某個模型添加功能,因此是部分類。
針對C#6進行了更新
C#6增加了為自動屬性分配默認值的功能。 值可以是任何表達式(它不必是常量)。 以下是一些例子:
// Initialize to a string literal
public string SomeProperty {get;set;} = "This is the default value";
// Initialize with a simple expression
public DateTime ConstructedAt {get;} = DateTime.Now;
// Initialize with a conditional expression
public bool IsFoo { get; } = SomeClass.SomeProperty ? true : false;
原始答案
自動實現的屬性可以在類構造函數中初始化,但不能在屬性本身上初始化。
public SomeModel
{
IsSomething = false;
SomeList = new List<string>();
}
...或者您可以使用字段支持的屬性(稍微多一些工作)並初始化字段本身...
private bool _IsSomething = false;
public bool IsSomething
{
get { return _IsSomething; }
set { _IsSomething = value; }
}
更新:我的上述答案並沒有澄清這部分課程的問題。 Mehrdad的答案提供了使用部分方法的解決方案,這符合我的第一個建議。 我的第二個建議是使用非自動實現的屬性(手動實現的屬性?)將適用於這種情況。
第一個屬性(IsSomething)是一個布爾值。 默認情況下它將是假的。
第二個屬性,因為它是引用類型,默認為null,而不需要您付出任何努力。 您不需要觸及構造函數,因為引用類型(類)將在.NET中自動從null開始。
如果您想使用非默認值,您有兩個選擇 -
首先,使用后備存儲字段:
private bool isSomething = true;
public bool IsSomething {
get { return this.isSomething; }
set { this.isSomething = value; }
}
第二個選項 - 將其添加到構造函數中。
請注意,第一個選項沒有額外的開銷 - 它基本上是編譯器在使用自動屬性時所執行的操作。
在部分類的兩個部分中不能有兩個構造函數。 但是,您可以使用部分方法來完成類似的操作:
// file1:
partial void Initialize();
public Constructor() {
// ... stuff ... initialize part 1
Initialize();
}
// file2:
void Initalize() {
// ... further initializations part 2 might want to do
}
如果partial類的任何部分都沒有定義partial方法,則將省略對它的所有調用。
警告WCF部分類的用戶
如果您嘗試將屬性添加到WCF代理類(由“添加服務引用”生成),您可能會驚訝地發現私有字段未初始化,因為顯然根本沒有調用構造函數 。
如果您嘗試這樣做(如其他一些答案所示),它將永遠不會被調用:
private bool _sendEmail = true;
這與該字段是否屬於部分類無關。
您需要做的是添加一個[OnDeserialized]屬性,該屬性允許您對該對象進行進一步的初始化。 這是System.Runtime.Serialization的一部分,因此僅在使用DataContractSerializer時在序列化的上下文中有用。
public partial class EndOfDayPackageInfo
{
[OnDeserialized()]
public void Init(StreamingContext context)
{
_sendEmail = true;
}
private bool _sendEmail;
public bool SendEmail
{
get
{
return _sendEmail;
}
set
{
_sendEmail = value;
RaisePropertyChanged("SendEmail");
}
}
}
另一種方法是'延遲加載'屬性 - 但這種方法不那么優雅。
private bool _sendEmail;
private bool _sendEmailInitialized;
public bool SendEmail
{
get
{
if (!_sendEmailInitialized)
{
_sendEmailInitialized = true;
_sendEmail = true; // default value
}
return _sendEmail;
}
set
{
if (!_sendEmailInitialized)
{
// prevent unwanted initialization if 'set' is called before 'get'
_sendEmailInitialized = true;
}
_sendEmail = value;
RaisePropertyChanged("SendEmail");
}
}
對此,不要使用自動屬性,而是使用舊方法
YourType _yourParameter = yourDefaultValue;
public YourType YourParameter
{
get{return _yourParameter;}
set{_yourParameter=value;}
}
對於C#6.0版的用戶,可以初始化這樣的屬性:
public bool IsSomething { get; set; } = true;
public List<string> SomeList { get; set; } = new List<string>();
您的屬性都已具有所需的默認值。
在部分類中使用構造函數沒有任何問題。 除了源代碼分布在多個文件/聲明中之外,部分類絕不是特殊的。
private bool _InternalUserContactUpdate = false;
public bool InternalUserContactUpdate
{
get { return _InternalUserContactUpdate; }
set { _InternalUserContactUpdate = value; }
}
然后當你想要覆蓋條件的值時,
if(!objUserModel.FirstName.ToLower().Equals(entry.Key[0].Attributes.Contains("firstname").ToString().ToLower()))
{
objUserModel.InternalUserContactUpdate= true;
}
希望這會有所幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.