【问题标题】:Properties and auto-implementations属性和自动实现
【发布时间】:2015-05-25 15:16:20
【问题描述】:

我在 Outlook 2013 的 VSTO 插件中使用 .NET 4.5。我在完全掌握属性和访问器时遇到了一些麻烦。我假设当你只写 get 时自动实现的访问器;放;而不是得到{ //code }等也给我带来麻烦。我有一本我在课堂上使用的字典。这是我的代码:

private Dictionary<string, string> clientDict { get; set; }
private Dictionary<string, string> clientHistoryDict { get; set; }

然后:

clientDict = new Dictionary<string, string>();
clientHistoryDict = new Dictionary<string, string>();

我稍后在同一个类中使用与代码中的属性相同的名称。

我从来没有真正写过:

private Dictionary<string, string> _clientDict; // etc.

创建变量我只是直接使用该属性。

我尝试更改我的代码来执行此操作,但遇到了一些问题,并意识到我对属性的理解有点混乱。

这里有几个问题我需要澄清,但我似乎找不到正确答案。

首先,是否有任何理由使用私有财产?我的字典永远不会在类之外或任何派生类中访问,所以有理由甚至使用属性吗?我不使用任何特殊的验证或设置器中的任何东西或类似的东西。

其次,当我尝试将代码更改为使用变量,然后像典型的属性示例那样通过属性访问它们时,我遇到了问题。我找到了一个示例,其中 getter 设置为 return _clientDict,但 setter 只是 set; 它给了我错误:我必须给 set 一个主体,因为它不是抽象的或部分的。为什么它不会在这种情况下为我自动实现 setter?

最后,当我对声明它的同一类中的属性调用 new 时,使用属性和相同类型的普通变量执行此操作有什么区别?在这种情况下,属性是否与变量完全不同?当应该使用私有变量来完成时,以这种方式使用属性是不好的做法吗?

这些可能是一些被误导的问题,但我找不到任何其他地方有信息可以帮助我理解这些区别。我一直在使用属性来尝试解决所有这些问题,但我可以使用我的帮助。

【问题讨论】:

    标签: c# properties field


    【解决方案1】:

    首先,有什么理由使用私有财产吗?

    通常,不会。属性非常适合封装。使用属性的一个优点(manymore)是它可以在分配之前进行验证。当您拥有private 的东西时,您通常不需要 保护这些东西免受您自己 的伤害。此外,属性具有设置不同访问器(privateprotected 等)的优势,而字段则没有。

    为什么它不会在这种情况下为我自动实现 setter?

    我们必须明白,自动实现的属性并不是黑魔法。编译器将为我们生成一个私有的支持字段,而不是我们自己提供一个。从他的角度来看,他看到您有一个返回私有字段的 getter,但 setter 是自动的,这通常表明您的代码中存在某种逻辑错误。为什么你会返回一个值但设置一个完全不同的值?当您创建带有支持字段的属性时,您必须同时提供 getter 和 setter,those are the rules

    当我在同一个类中的属性上调用 new 时 在声明中,使用属性执行此操作有什么区别 和同类型的普通变量?

    语义上,没什么new 属于正在构造的类型,将发出构造函数调用。不同之处在于新创建的对象被分配。字段将导致编译器发出stfld 操作码。对于属性,它将发出 call 来调用属性设置器。当您访问一个属性时,编译器最终会在字段上调用get_YourPropertyName 而不是ldfld

    在应该使用的时候以这种方式使用属性是不好的做法吗? 用私有变量完成?

    我不会称之为不好的做法,但我会觉得拥有私有财产有点奇怪。

    有关字段和属性的更多见解,请参阅What is the difference between a Field and a Property in C#?

    【讨论】:

    • 非常感谢,只是一些澄清?字段不能有访问说明符是什么意思?私有成员变量不就是一个例子吗?我想我错过了你所说的字段。
    • 私有属性的论点是未来变化的潜力。尽管您现在没有验证逻辑,但将来可能会,并且已经拥有一个属性为您提供了一个更改此逻辑的位置,而不是在您的类中发生每个位置分配,从而使您的类不变量更易于维护。它可能不是一个伟大的论据,尤其是在所有情况下,但它可以帮助封装某些类型的波动性。
    • @shenk 属性可以这样做:public string Foo { get; protected set; },这意味着只有派生类型可以设置Foo 的值。字段无法做到这一点。
    • @PrestonGuillot 但是私有字段是实现细节,重构它不需要外部的任何知识。当您使用一个属性时,您通常希望保护自己免受未来对公共 API 的更改。我还没有看到对程序员来说不是错误的私有财产。
    • 这不是使用属性的唯一原因。除了验证逻辑之外,您还可以在 getter 或 setter 中运行各种代码。例如,您可能在 setter 中有一些 OnValueChanged()(INPC 就是一个例子)。这不能用字段来完成。
    【解决方案2】:

    有什么理由使用私有财产吗?

    不,这就是自动实现的重点。当您想要做的只是获取或设置私有成员变量中的内容时,您不必编写所有额外的代码。 .Net 在幕后处理影子私有成员变量的创建。

    当我尝试更改我的代码以使用变量,然后像典型的属性示例那样通过属性访问它们时,我遇到了问题。我找到了一个示例,其中 getter 设置为返回 _clientDict,但 setter 刚刚设置;它给了我一个错误:我必须给 set 一个主体,因为它不是抽象的或部分的。为什么它不会在这种情况下为我自动实现 setter?

    我的理解是,自动实现要么全有,要么全无。 (尽管在那里可以更正)。也就是说,我已经看到使用简单定义为 set { } 的 set 块编译代码。 编辑:只是为了澄清 set { } 块实际上不会设置值,它基本上吞下了调用并且什么都不做 - 但它会编译。

    当我在声明它的同一类中的属性上调用 new 时,使用属性和相同类型的普通变量执行此操作有什么区别?在这种情况下,属性是否与变量完全不同?当应该使用私有变量来完成时,以这种方式使用属性是不好的做法吗?

    据我所知,没有真正的区别。完全相同的事情正在发生,只是 .Net 正在为您处理管道。

    【讨论】:

      猜你喜欢
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多