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

Roe*_*ler 20 c# default properties partial-classes

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

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

public partial class SomeModel
{
    public bool IsSomething { get; set; }
    public List<string> SomeList { get; set; }

    ... Additional methods using the above data members ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢

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

STW*_*STW 38

针对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;
Run Code Online (Sandbox Code Playgroud)

原始答案

自动实现的属性可以在类构造函数中初始化,但不能在属性本身上初始化.

public SomeModel
{
    IsSomething = false;
    SomeList = new List<string>();
}
Run Code Online (Sandbox Code Playgroud)

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

private bool _IsSomething = false;
public bool IsSomething
{
    get { return _IsSomething; }
    set { _IsSomething = value; }
}
Run Code Online (Sandbox Code Playgroud)

更新:我的上述答案并没有澄清这部分课程的问题. Mehrdad的答案提供了使用部分方法的解决方案,这符合我的第一个建议.我的第二个建议是使用非自动实现的属性(手动实现的属性?)将适用于这种情况.


Ree*_*sey 8

第一个属性(IsSomething)是一个布尔值.默认情况下它将是假的.

第二个属性,因为它是引用类型,默认为null而不需要您付出任何努力.您不需要触及构造函数,因为引用类型(类)将在.NET中自动从null开始.

如果您想使用非默认值,您有两个选择 -

首先,使用后备存储字段:

private bool isSomething = true;
public bool IsSomething {
    get { return this.isSomething; }
    set { this.isSomething = value; }
}
Run Code Online (Sandbox Code Playgroud)

第二个选项 - 将其添加到构造函数中.

请注意,第一个选项没有额外的开销 - 它基本上是编译器在使用自动属性时所执行的操作.


Meh*_*ari 5

在部分类的两个部分中不能有两个构造函数.但是,您可以使用部分方法来完成类似的操作:

// file1:
partial void Initialize();
public Constructor() {
    // ... stuff ... initialize part 1
    Initialize();
}

// file2:
void Initalize() {
    // ... further initializations part 2 might want to do
}
Run Code Online (Sandbox Code Playgroud)

如果partial类的任何部分都没有定义partial方法,则将省略对它的所有调用.


Sim*_*ver 5

警告WCF部分类的用户

如果您尝试将属性添加到WCF代理类(由"添加服务引用"生成),您可能会惊讶地发现私有字段未初始化,因为显然根本没有调用构造函数.

如果您尝试这样做(如其他一些答案所示),它将永远不会被调用:

    private bool _sendEmail = true;
Run Code Online (Sandbox Code Playgroud)

这与该字段是否属于部分类无关.

您需要做的是添加一个[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");
        }
    }
Run Code Online (Sandbox Code Playgroud)

}

另一种方法是'延迟加载'属性 - 但这种方法不那么优雅.

    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");
        }
    }
Run Code Online (Sandbox Code Playgroud)