简体   繁体   English

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

[英]C#: How to set default value for a property in a partial class?

I'm very new to C# so please bear with me... 我对C#很新,所以请耐心等待......

I'm implementing a partial class, and would like to add two properties like so: 我正在实现一个部分类,并希望添加两个属性,如下所示:

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

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

I would like to initialize both data members: IsSomething to True and SomeList to new List<string>() . 我想初始化两个数据成员: IsSomethingTrueSomeListnew List<string>() Normally I would do it in a constructor, however because it's a partial class I don't want to touch the constructor (should I?). 通常我会在构造函数中执行它,但是因为它是一个部分类我不想触及构造函数(我应该吗?)。

What's the best way to achieve this? 实现这一目标的最佳方法是什么?

Thanks 谢谢

PS I'm working in ASP.NET MVC, adding functionality to aa certain model, hence the partial class. PS我在ASP.NET MVC中工作,为某个模型添加功能,因此是部分类。

Updated for C# 6 针对C#6进行了更新

C# 6 has added the ability to assign a default value to auto-properties. C#6增加了为自动属性分配默认值的功能。 The value can be any expression (it doesn't have to be a constant). 值可以是任何表达式(它不必是常量)。 Here's a few examples: 以下是一些例子:

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

Original Answer 原始答案

Automatically implemented properties can be initialized in the class constructor, but not on the propery itself. 自动实现的属性可以在类构造函数中初始化,但不能在属性本身上初始化。

public SomeModel
{
    IsSomething = false;
    SomeList = new List<string>();
}

...or you can use a field-backed property (slightly more work) and initialize the field itself... ...或者您可以使用字段支持的属性(稍微多一些工作)并初始化字段本身...

private bool _IsSomething = false;
public bool IsSomething
{
    get { return _IsSomething; }
    set { _IsSomething = value; }
}

Update: My above answer doesn't clarify the issue of this being in a partial class. 更新:我的上述答案并没有澄清这部分课程的问题。 Mehrdad's answer offers the solution of using a partial method, which is in line with my first suggestion. Mehrdad的答案提供了使用部分方法的解决方案,这符合我的第一个建议。 My second suggestion of using non-automatically implemented properties (manually implemented properties?) will work for this situation. 我的第二个建议是使用非自动实现的属性(手动实现的属性?)将适用于这种情况。

The first property (IsSomething) is a boolean. 第一个属性(IsSomething)是一个布尔值。 It will be false by default. 默认情况下它将是假的。

The second property, since it's a reference type, will default to null without any effort on your part. 第二个属性,因为它是引用类型,默认为null,而不需要您付出任何努力。 You don't need to touch the constructor, since reference types (classes) will automatically start off as null in .NET. 您不需要触及构造函数,因为引用类型(类)将在.NET中自动从null开始。

If you wanted to use a non-default value, you'd have two options - 如果您想使用非默认值,您有两个选择 -

First, use a backing storage field: 首先,使用后备存储字段:

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

Second option - add it to the constructor. 第二个选项 - 将其添加到构造函数中。

Note that the first option has no extra overhead - it's basically what the compiler does when you use an automatic property. 请注意,第一个选项没有额外的开销 - 它基本上是编译器在使用自动属性时所执行的操作。

You can't have two constructors in two parts of a partial class. 在部分类的两个部分中不能有两个构造函数。 However, you can use partial methods to accomplish something like it: 但是,您可以使用部分方法来完成类似的操作:

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

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

If no parts of a partial class defines the partial method, all calls to it would be omitted. 如果partial类的任何部分都没有定义partial方法,则将省略对它的所有调用。

WARNING for users of WCF partial classes 警告WCF部分类的用户

If you're trying to add a property to a WCF proxy class (generated by Add Service Reference) you might be surprised to find that private fields aren't initialized because apparently no constructor at all is called . 如果您尝试将属性添加到WCF代理类(由“添加服务引用”生成),您可能会惊讶地发现私有字段未初始化,因为显然根本没有调用构造函数

If you attempt to do this (as suggested in some other answers) it won't ever get called : 如果您尝试这样做(如其他一些答案所示),它将永远不会被调用:

    private bool _sendEmail = true;

This has nothing to do with whether the field is in a partial class or not. 这与该字段是否属于部分类无关。

What you have to do is add an [OnDeserialized] attribute which lets you do further initialization to the object. 您需要做的是添加一个[OnDeserialized]属性,该属性允许您对该对象进行进一步的初始化。 This is part of System.Runtime.Serialization so is only useful in the context of serialization when using DataContractSerializer . 这是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");
        }
    }

} }

Another approach is to 'lazy load' the property - but this approach is much less elegant. 另一种方法是'延迟加载'属性 - 但这种方法不那么优雅。

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

To this, don't use automatic property but the old way 对此,不要使用自动属性,而是使用旧方法

YourType _yourParameter = yourDefaultValue;
public YourType YourParameter
{
   get{return _yourParameter;}
   set{_yourParameter=value;}
}

For user of version 6.0 of C#, it's possible to initialize the properties like this : 对于C#6.0版的用户,可以初始化这样的属性:

public bool IsSomething { get; set; } = true;
public List<string> SomeList { get; set; } = new List<string>();

Both your properties will already have the default values you require. 您的属性都已具有所需的默认值。

There is nothing wrong with having a constructor in a partial class. 在部分类中使用构造函数没有任何问题。 Partial classes are in no way special, aside from the fact that their source code is spread across multiple files/declarations. 除了源代码分布在多个文件/声明中之外,部分类绝不是特殊的。

 private bool _InternalUserContactUpdate = false;
        public bool InternalUserContactUpdate
        {
            get { return _InternalUserContactUpdate; }
            set { _InternalUserContactUpdate = value; }
        }

Then when you want to override the value on condition, 然后当你想要覆盖条件的值时,

if(!objUserModel.FirstName.ToLower().Equals(entry.Key[0].Attributes.Contains("firstname").ToString().ToLower()))
        {
             objUserModel.InternalUserContactUpdate= true;
        }

Hope this will help 希望这会有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 C# 中设置作为类的属性的值 - How to set value of a property that is a class in C# 如何在 C# 中将属性设置为默认值? - How do I set a property to a default value in C#? C#自动生成的部分类重新定义属性获取设置 - c# auto generated partial class redefine property get set 在c#中将默认值设置为成员类 - Set default value to member class in c# 在类构造函数C#中设置默认值 - set default value in class constructor C# 我可以在ac#class中设置一个属性,以便始终具有特定的默认值吗? - Can I set a property in a c# class to always have a specific default value? 当属性为类时,如何为C#自动属性赋予默认值 - How do you give a C# Auto-Property a default value When the Property is a Class 如何将一个类属性的值设置为 C# 中另一个泛型列表中的另一个类属性? - How to set a value of one class property to another class property in another generic list in C#? 有没有一种优雅的方法来为c#中的属性设置默认值? - Is there an elegant way to set a default value for a property in c#? C# AutoMapper - 如果源中不存在,则在 dest 属性中设置默认值 - C# AutoMapper - Set default value in dest property if not exist in source
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM