C#:如何为分部类中的属性设置默认值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1272602/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C#: How to set default value for a property in a partial class?
提问by Roee Adler
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>()
. 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?).
我想初始化两个数据成员:IsSomething
toTrue
和SomeList
to new List<string>()
。通常我会在构造函数中这样做,但是因为它是一个部分类,我不想接触构造函数(我应该这样做吗?)。
What's the best way to achieve this?
实现这一目标的最佳方法是什么?
Thanks
谢谢
PS I'm working in ASP.NET MVC, adding functionality to a a certain model, hence the partial class.
PS 我在 ASP.NET MVC 中工作,向某个模型添加功能,因此是部分类。
采纳答案by STW
Updated for C# 6
为 C# 6 更新
C# 6 has added the ability to assign a default value to auto-properties. The value can be any expression (it doesn't have to be a constant). Here's a few examples:
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;
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 answeroffers the solution of using a partial method, which is in line with my first suggestion. My second suggestion of using non-automatically implemented properties (manually implemented properties?) will work for this situation.
更新:我上面的回答并没有澄清这是在一个部分类中的问题。 Mehrdad 的回答提供了使用部分方法的解决方案,这符合我的第一个建议。我使用非自动实现的属性(手动实现的属性?)的第二个建议将适用于这种情况。
回答by Reed Copsey
The first property (IsSomething) is a boolean. It will be false by default.
第一个属性 (IsSomething) 是一个布尔值。默认情况下它会是假的。
The second property, since it's a reference type, will default to null without any effort on your part. You don't need to touch the constructor, since reference types (classes) will automatically start off as null in .NET.
第二个属性,因为它是一个引用类型,将默认为 null,而无需您做任何努力。您不需要接触构造函数,因为在 .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.
请注意,第一个选项没有额外的开销 - 基本上是编译器在您使用自动属性时所做的。
回答by Paul Turner
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.
在分部类中使用构造函数并没有错。除了它们的源代码分布在多个文件/声明中这一事实之外,部分类并没有什么特别之处。
回答by Mehrdad Afshari
You can't have two constructors in two parts of a partial class. However, you can use partial methodsto 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.
如果分部类的任何部分都没有定义分部方法,则将省略对其的所有调用。
回答by Gregtheitroade
To this, don't use automatic property but the old way
为此,不要使用自动属性,而是使用旧方法
YourType _yourParameter = yourDefaultValue;
public YourType YourParameter
{
get{return _yourParameter;}
set{_yourParameter=value;}
}
回答by Simon_Weaver
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. This is part of System.Runtime.Serialization so is only useful in the context of serialization when using DataContractSerializer.
您需要做的是添加一个[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");
}
}
}
}
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");
}
}
回答by Ant
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>();
回答by Subhamay
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
希望这会有所帮助