我在Outlook 2013的VSTO插件中使用.NET 4.5。我在完全掌握属性和访问器方面遇到了一些麻烦。我假设的自动实现的访问器就是你刚刚写的get;组;而不是得到{// code}等等也给我带来了麻烦。我有一本我在班上内部使用的词典。这是我的代码:
protected void Page_Load(object sender, EventArgs e)
{
trComment.Visible = false; //or trComment.Visible = true; as you wish
}
然后在以后:
private Dictionary<string, string> clientDict { get; set; }
private Dictionary<string, string> clientHistoryDict { get; set; }
我在稍后的代码中使用的名称与同一类中的属性相同。
我从未写过:
clientDict = new Dictionary<string, string>();
clientHistoryDict = new Dictionary<string, string>();
创建我直接使用该属性的变量。
我尝试更改我的代码来执行此操作,我遇到了一些问题,并意识到我对属性的理解有点混乱。
以下是一些我需要澄清的问题,我似乎无法找到正确答案。
首先,有没有理由使用私有财产?我的字典永远不会在类之外或任何派生类中访问,所以是否有理由使用属性?我不会使用任何特殊的验证或者setter中的任何东西或类似的东西。
其次,当我尝试更改我的代码以使用变量,然后通过像典型属性示例那样的属性访问它们时,我遇到了问题。我找到了一个例子,其中getter设置为private Dictionary<string, string> _clientDict; // etc.
,但是setter只是return _clientDict
它给了我错误:我必须设置一个body,因为它不是抽象的或部分的。为什么在这种情况下它不会为我自动实现setter?
最后,当我在声明它的同一个类中的属性上调用new时,使用属性和相同类型的普通变量之间的区别是什么?在这种情况下,属性是否与变量完全不同?当应该使用私有变量完成时,以这种方式使用属性是不好的做法吗?
这些可能是一些误入歧途的问题,但我找不到任何其他有信息帮助我理解这些区别的地方。我一直在玩房产试图解决所有问题,但我可以帮助我。
答案 0 :(得分:11)
首先,有没有理由使用私有财产?
通常,没有。属性非常适合封装。使用属性的一个优点(有many more)是它可以在赋值之前进行验证。当您拥有private
内容时,通常不会需要来保护您自己的内容。此外,属性还具有设置不同访问者(private
,protected
等)的优势,而字段则不然。
为什么在这种情况下它不会为我自动实现setter?
我们必须明白,自动实现的属性不是黑魔法。编译器将为我们生成一个私有支持字段,而不是提供一个selfelfs。从他的角度来看,他看到你有一个返回私有字段的getter,但是setter是自动的,通常会在你的代码中指出某种逻辑错误。为什么你会返回一个值,但设置一个完全不同的值?当您使用支持字段创建属性时,您必须同时提供getter和setter those are the rules。
当我在同一个类中的属性上调用new时 声明,与财产这样做有什么区别 和一个相同类型的正常变量?
从语义上讲,没什么。 new
属于正在构造的类型,并将发出构造函数调用。区别在于新创建的对象已分配。字段将导致编译器发出stfld
操作码。对于属性,它将发出call
来调用属性设置器。当您访问某个属性时,编译器最终会在该字段上调用get_YourPropertyName
vs ldfld
。
在应该使用属性时,这是不好的做法 用私有变量完成?
我不会称之为不好的做法,但我觉得拥有私人财产有点奇怪。
有关字段和属性的更多见解,请参阅What is the difference between a Field and a Property in C#?
答案 1 :(得分:3)
有没有理由使用私有财产?
不 - 这是汽车实施的重点。当你想要做的就是获取或设置私有成员变量中的内容时,它可以节省你必须编写所有额外代码。 .Net处理在幕后创建阴影私有成员变量。
当我尝试更改我的代码以使用变量然后通过属性(例如典型属性示例)访问它们时,我遇到了问题。我找到了一个例子,其中getter设置为返回_clientDict,但是setter只是设置了;它给了我一个错误:我必须设置一个正文,因为它不是抽象的或部分的。为什么在这种情况下它不会为我自动实现setter?
我的理解是它与汽车实现有关或全无。 (虽然可以在那里进行修正)。也就是说我看到代码编译时使用的set块简单地定义为set { }
。 编辑:只是为了澄清实际设置值的set { }
块,它基本上吞下了调用而什么都不做 - 它会编译。
当我在声明它的同一个类中的属性上调用new时,使用属性和相同类型的普通变量之间的区别是什么?在这种情况下,属性是否与变量完全不同?当应该使用私有变量完成时,以这种方式使用属性是不好的做法吗?
据我所知,没有真正的区别。发生了同样的事情,只是.Net正在为你处理管道。