23

我对 C# 很陌生,所以请多多包涵……

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

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

    ... Additional methods using the above data members ...
}

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

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

谢谢

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

4

8 回答 8

41

针对 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 的回答提供了使用部分方法的解决方案,这符合我的第一个建议。我使用非自动实现的属性(手动实现的属性?)的第二个建议将适用于这种情况。

于 2009-08-13T15:15:46.720 回答
9

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

第二个属性,因为它是一个引用类型,将默认为 null ,而无需您做任何努力。您无需接触构造函数,因为引用类型(类)在 .NET 中将自动以 null 开始。

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

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

private bool isSomething = true;
public bool IsSomething {
    get { return this.isSomething; }
    set { this.isSomething = value; }
}

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

请注意,第一个选项没有额外的开销 - 它基本上是编译器在您使用自动属性时所做的事情。

于 2009-08-13T15:15:42.400 回答
6

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

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

// file2:
void Initalize() {
    // ... further initializations part 2 might want to do
}

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

于 2009-08-13T15:17:01.383 回答
5

警告 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");
        }
    }
于 2010-12-01T03:09:15.843 回答
4

为此,不要使用自动属性,而是使用旧方法

YourType _yourParameter = yourDefaultValue;
public YourType YourParameter
{
   get{return _yourParameter;}
   set{_yourParameter=value;}
}
于 2009-08-13T15:20:11.160 回答
3

对于 C# 6.0 版的用户,可以像这样初始化属性:

public bool IsSomething { get; set; } = true;
public List<string> SomeList { get; set; } = new List<string>();
于 2016-03-16T14:37:17.097 回答
1

您的两个属性都已经具有您需要的默认值。

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

于 2009-08-13T15:16:40.557 回答
0
 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;
        }

希望这会有所帮助

于 2017-08-13T03:49:12.360 回答