C#:如何为分部类中的属性设置默认值?

我对C#很新,所以请耐心等待……

我正在实现一个部分类,并希望添加两个属性,如下所示:

public partial class SomeModel { public bool IsSomething { get; set; } public List SomeList { get; set; } ... Additional methods using the above data members ... } 

我想初始化两个数据成员: IsSomethingTrueSomeListnew List() 。 通常我会在构造函数中执行它,但是因为它是一个部分类我不想触及构造函数(我应该吗?)。

实现这一目标的最佳方法是什么?

谢谢

PS我在ASP.NET MVC中工作,为某个模型添加function,因此是部分类。

针对C#6进行了更新

C#6增加了为自动属性分配默认值的function。 值可以是任何表达式(它不必是常量)。 以下是一些例子:

 // 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(); } 

…或者您可以使用字段支持的属性(稍微多一些工作)并初始化字段本身…

 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 SomeList { get; set; } = new List(); 

您的属性都已具有所需的默认值。

在部分类中使用构造函数没有任何问题。 除了源代码分布在多个文件/声明中之外,部分类绝不是特殊的。

  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; } 

希望这会有所帮助