我们经常被告知我们应该通过为类字段制作getter和setter方法(C#中的属性)来保护封装,而不是将字段暴露给外部世界.
但是很多时候,一个字段只是用来保存一个值,并且不需要任何计算来获取或设置.对于这些,我们都会这样做:
public class Book
{
private string _title;
public string Title
{
get{ return _title; }
set{ _title = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,我有一个坦白,我不忍心写所有这些(真的,它不必写它,它不得不看它),所以我去流氓和使用公共领域.
然后是C#3.0,我看到他们添加了自动属性:
public class Book
{
public string Title {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
这更整洁,我很感激它,但是真的,除了创建一个公共领域之外还有什么不同?
public class Book
{
public string Title;
}
Run Code Online (Sandbox Code Playgroud) 我习惯写这样的课程:
public class foo {
private string mBar = "bar";
public string Bar {
get { return mBar; }
set { mBar = value; }
}
//... other methods, no constructor ...
}
Run Code Online (Sandbox Code Playgroud)
将Bar转换为自动属性看起来既方便又简洁,但是如何在不添加构造函数并将初始化放在那里的情况下保留初始化?
public class foo2theRevengeOfFoo {
//private string mBar = "bar";
public string Bar { get; set; }
//... other methods, no constructor ...
//behavior has changed.
}
Run Code Online (Sandbox Code Playgroud)
您可以看到添加构造函数并不符合我应该从自动属性中获得的省力.
这样的事情对我来说更有意义:
public string Bar { get; set; } = "bar";
Run Code Online (Sandbox Code Playgroud) 我开始知道C#3.0带有Auto-Implemented Properties的新功能,我喜欢它,因为我们不必在此声明额外的私有变量(与之前的属性相比),之前我使用的是属性,即
private bool isPopup = true;
public bool IsPopup
{
get
{
return isPopup;
}
set
{
isPopup = value;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我已将其转换为Auto-Implemented属性即
public bool IsPopup
{
get; set;
}
Run Code Online (Sandbox Code Playgroud)
我想将此属性的默认值设置为true而不使用它甚至在page_init方法中,我尝试但没有成功,任何人都可以解释如何做到这一点?
我只是回顾一些旧的代码(有一些空闲时间),我注意到一个相当冗长的switch语句.由于获得了新知识,我已经以下面的形式重构了它:
private Dictionary<string, Action> createView
{
get
{
return new Dictionary<string, Action>()
{
{"Standard", CreateStudySummaryView},
{"By Group", CreateStudySummaryByGroupView},
{"By Group/Time", CreateViewGroupByHour}
};
}
}
Run Code Online (Sandbox Code Playgroud)
你会考虑这个好习惯,还是仅仅是一个超级丰富和不必要的案例?我渴望确保我学到的新技术,仅仅为了它而不是聪明,并且它们实际上为代码增加了好处.
谢谢.
我有以下自动属性
[DefaultValue(true)]
public bool RetrieveAllInfo { get; set; }
Run Code Online (Sandbox Code Playgroud)
当我尝试在代码中使用它时我发现默认的false假设是因为我认为这是bool变量的默认值,有没有人知道什么是错的!?
可能重复:
如何为C#Auto-Property提供默认值?
有没有什么好方法可以为自动属性提供默认值?
public int HowHigh { get; set; } // defaults to 0
如果没有在任何地方明确设置,我希望它是5.你知道一个简单的方法吗?例如,我可以在构造函数或其他东西中设置它,但这并不优雅.
更新:C#6得到了它:http://geekswithblogs.net/WinAZ/archive/2015/06/30/whatrsquos-new-in-c-6.0-auto-property-initializers.aspx
那里有很多建议你不应该公开地公开你的字段,而是使用普通的属性.我一遍又一遍地看到它.
我理解这些论点,但在大多数情况下我认为这不是一个好建议.
有没有人有一个真正重要的时间的例子?在写一个琐碎的财产时,将来可能会有一些重要的事情(或者当没有使用它时会让他们陷入真正的麻烦)?
编辑:DataBinding参数是正确的,但不是很有趣.DataBinding代码中的一个错误是它不接受公共字段.因此,我们必须编写属性来解决该bug,而不是因为属性是明智的类设计选择.
编辑:要清楚,我正在寻找现实世界的例子,而不是理论.真正重要的时刻.
编辑:在setter上设置断点的能力似乎很有价值.为调试器设计我的代码是不幸的:我宁愿调试器变得更聪明,但考虑到我们的调试器,我将采用这种能力.好东西.
我有一个现有的表/模型,我想删除一个新的布尔列.该表已有数百行数据,我无法触及现有数据.但是..这个列不可为空,所以我需要为true当前存在的所有行提供默认值.
public class Revision
{
...
public Boolean IsReleased { get; set; }
....
}
Run Code Online (Sandbox Code Playgroud)
重要:
(这是在OP,但人们似乎错过了.)
使用迁移更新数据库时,接收此新列的所有现有行必须将其值设置为True.
想象一下,你在课堂上有一个字段_items.您可以在声明点初始化它:
class C
{
IList<string> _items=new List<string>();
}
Run Code Online (Sandbox Code Playgroud)
现在我想将此字段转换为自动生成的属性,但现在初始化无效:
class C
{
public IList<string> Items=new List<string>(); {get; set;} // Invalid
}
Run Code Online (Sandbox Code Playgroud)
所以,我必须这样做:
class C
{
public IList<string> Items {get; set;}
public C
{
Items=new List<string>();
}
}
Run Code Online (Sandbox Code Playgroud)
但这并不像在声明点初始化字段那样方便.有没有更好的方法来执行此操作,而不必(不必要地)使用私有(在声明点初始化)字段来支持此属性,例如.
谢谢
嗨伙计们下面的两段代码有什么区别吗?或者顶部只是底部的一个简短形式?
public string Name{get;set;}
Run Code Online (Sandbox Code Playgroud)
和
private string _Name;
public string Name
{
get { return _Name; }
set { _Name=value; }
}
Run Code Online (Sandbox Code Playgroud) c# ×10
properties ×3
.net ×1
asp.net ×1
attributes ×1
c#-4.0 ×1
class ×1
field ×1
polymorphism ×1
refactoring ×1