Mat*_*hew 36 c# coding-style field properties
我对C#很新,我认为属性是一件很棒的事情.事实上,如此精彩,我看不到使用字段的任何真正优势.即使对于私人领域,性能提供的灵活性和模块性似乎最多可以避免严重的麻烦,最糟糕的是根本没有效果.
我可以在字段中看到的唯一优势是您可以内联初始化它们.但是大多数时候,你想在构造函数中初始化它们.如果您不使用内联初始化,是否有任何理由不使用属性?
编辑:有些人提出需要使用字段备份属性(显式或自动).让我们澄清一下我的问题:除了备份属性之外,有没有理由使用字段?也就是说,有没有比这SomeType someField;
更好的时间了SomeType SomeProperty { get; set; }
?
编辑2:DanM,Skurmedel和Seth都提供了非常有用的答案.我已经接受了DanM,因为它是最完整的,但如果有人将他们的回答总结为一个答案,我会很乐意接受它.
dev*_*xer 25
通常,属性需要一个支持字段,除非它们是简单的getter/setter"自动属性".
所以,如果你只是......
public string Name { get; set; } // automatic property
Run Code Online (Sandbox Code Playgroud)
......你不需要一个领域,我同意,没有理由拥有一个领域.
但是,如果你正在......
public string Name
{
get { return _name; }
set
{
if (value = _name) return;
_name = value;
OnPropertyChange("Name");
}
}
Run Code Online (Sandbox Code Playgroud)
......你需要那个_name
支持领域.
对于不需要任何特殊get/set逻辑的私有变量,它实际上是一个判断调用,无论是私有自动属性还是只是一个字段.我通常做一个字段,然后,如果我需要它,protected
或者public
,我会将它改为自动属性.
更新
正如Yassir所指出的,如果你使用自动属性,那么幕后仍然会有一个潜伏的场地,这不是你实际需要输入的东西.因此,底线是:属性不存储数据,它们提供对数据的访问.字段是实际保存数据的内容.所以,即使你看不到它们,你也需要它们.
更新2
关于你修改过的问题......
有没有时间SomeType someField; 比较
SomeType SomeProperty { get; set; }
好吗?
......有一件事情会浮现在脑海中:如果你有一个私人领域,并且(根据私人领域的惯例),你可以打电话给它_name
,并向你和任何阅读你的代码的人发出信号,表明你正在使用私人数据.另一方面,如果你把所有东西都作为属性,并且(根据属性的约定)调用你的私有属性Name
,现在你不能只看变量并告诉它是私有数据.因此,仅使用属性会删除一些信息.我没有尝试过与所有房产合作来衡量这是否是关键信息,但肯定会丢失一些东西.
另一件事,更轻微的是,public string Name { get; set; }
需要更多的打字(并且有点麻烦)private string _name
.
Set*_*eth 12
属性是一件很棒的事情 - 但是存在与属性访问相关的开销.不一定是问题,但需要注意的事项.
避免过度使用财产吸气剂和二传手
大多数人都没有意识到,在开销方面,属性getter和setter与方法类似; 它主要是区分它们的语法.除了字段访问之外不包含任何指令的非虚拟属性getter或setter将由编译器内联,但在许多其他情况下,这是不可能的.你应该仔细考虑你对财产的使用; 从类内部直接访问字段(如果可能),并且从不盲目地重复调用属性而不将值存储在变量中.总而言之,这并不意味着你应该使用公共领域!
资料来源:http://dotnet.sys-con.com/node/46342
Jen*_*enk 12
在使用ref/out args时尝试使用Property:
someObject.SomeMethod(ref otherObject.SomeProperty);
Run Code Online (Sandbox Code Playgroud)
它不会编译.
Sku*_*del 10
如果你想拥有一些东西,readonly
你几乎必须使用一个字段,因为没有办法告诉自动属性生成一个只读字段.
我经常这样做.
举例:
class Rectangle
{
private readonly int _width;
private readonly int _height;
public Rectangle(int width, int height)
{
_width = width;
_height = height;
}
public int Width { get { return _width; } }
public int Height { get { return _height; } }
}
Run Code Online (Sandbox Code Playgroud)
这意味着Rectangle内部的任何内容都不能改变构造后的宽度或高度.如果一个人试图编译器会抱怨.
如果我使用私有setter的自动属性,编译器将不会保护我自己.
我看到的另一个原因是,如果一块数据不必暴露(停留private
)为什么要将它作为财产?
小智 5
我不明白你为什么要使用私有自动属性。有什么好处可以
private int Count {get; set;}
Run Code Online (Sandbox Code Playgroud)
超过
private int count
Run Code Online (Sandbox Code Playgroud)
尽管我同意David Basarab声明中的“意图”:“没有理由公开展示字段”,但我想强调一点不同:
我将上面David的引言修改为:“没有理由公开公开……在类之外……除非有意识地选择将字段封装在Properties中,以严格控制访问。
属性不仅是“附加到” C#字段上的语法的“转折点”:它们是一种基本的语言功能,其设计基于以下充分的理由,包括:
控制在类之外公开和不公开的内容(封装,数据隐藏)
允许在访问或设置属性时执行某些操作:最好在属性“ get”和“ set”中表示的操作,而不是“提升”到外部定义的方法。
设计上的接口无法定义'fields :,但可以定义属性。
好的OO设计意味着有意识地选择“状态”:
局部变量字段:什么状态对方法是私有的,并且是瞬态的:局部变量通常仅在方法主体的范围内有效,甚至在“ for循环”之类的范围内有效。当然,您也可以将方法中的参数变量也视为“局部”。
类实例字段:什么状态是类专有的,并且对于类的每个实例具有独立的存在性,但是很可能需要在类中的多个位置使用。
静态实例字段:什么状态将仅是该类的属性,而与该类的实例数量无关。
状态故意并有意识地暴露在类的“外部”:关键思想是,在类和类的“消费者”所暴露的数据之间至少存在一个间接级别。当然,“暴露”的“反面”是有意识地隐藏(封装,隔离)实现代码。
一种。通过公共财产:这里的所有其他答案都涵盖了这个方面
b。通过索引器
C。通过方法
d。公共静态变量通常在实用程序类(通常是静态类)中找到。
建议您评论:关于“字段 ”的MSDN ... 关于属性的MSDN ... 关于索引器的MSDN