c# 使用基类中的 setter 或 getter

Posted

技术标签:

【中文标题】c# 使用基类中的 setter 或 getter【英文标题】:c# using setters or getters from base class 【发布时间】:2010-09-26 15:17:55 【问题描述】:

是否建议将基类的成员变量设置为protected,以便子类可以访问这些变量?还是更推荐将成员变量设置为private,让子类通过getter和setter来获取或设置变量?

如果推荐使用getter和setters方法,什么时候使用protected变量?

【问题讨论】:

【参考方案1】:

这与this question 非常相似,关于是通过属性访问同一类内的信息还是直接访问。可能也值得阅读所有这些答案。

就个人而言,我不喜欢任何字段都是非私有的,除了具有不可变值(无论是否为 const)的静态只读字段偶尔例外。对我来说,属性只是提供了更好的封装程度。如何存储数据是一个实现决定,而不是一个API决定(与属性不同)。为什么派生自类 Bar 的类 Foo 应该关心类 Bar 的实现

简而言之,我总是选择属性,除了一次性测试代码之外,我不使用受保护的变量。

借助 C# 3.0 中自动实现的属性,将字段转换为属性比以往任何时候都容易。没有理由这样做。

【讨论】:

【参考方案2】:

这是一个权衡。 Setter 和 getter 比直接访问字段要慢一些,所以如果你正在做大量的数学运算并且在你的子类中读/写这些字段很多,你应该直接访问这些字段。但这更像是一个例外。

通常,您应该将它们标记为私有并使用 getter/setter。

所以我的回答是:直接访问频繁使用的字段,否则为 getter/setter。使用常识

编辑:我做了一些分析,显然即使在发布模式下,字段和属性之间的速度差异也可能高达 20%。 请在此处查看我的测试用例:http://pastebin.com/m5a4d1597

【讨论】:

如果属性中没有逻辑,则在发布模式下,JIT 无论如何都会内联属性访问,因此不会对性能造成任何影响。 我已经详细介绍了它;直接(微不足道)属性没有性能损失;在某些测试中,它实际上变得更快,但我怀疑是宇宙射线干扰了测试;-p 我已经尝试过您的测试(使用秒表和 10 倍的迭代以获得更好的计时)。我没有看到 20% 的差异 - 但我确实看到了约 5% 的变化,这让我感到惊讶。进一步研究... @Greg:我认为测试大部分是合理的。仅仅因为有加速它的方法并不意味着它没有一个有趣的观点。无论如何,编译器都应该能够内联属性。我尝试将字段设为私有,但属性没有加快。 (我还没有尝试密封类。这当然很有趣。我目前正在尝试整数而不是双精度。)【参考方案3】:

其他程序集中的类可以派生自您的未密封类,并且可以访问受保护的字段。如果有一天您决定将这些字段设置为属性,则其他程序集中的这些类将需要重新编译才能与您的程序集的新版本一起使用。这被称为“破坏二进制兼容性”,这也许是您永远不应该在程序集之外公开字段的一个可靠原因。

【讨论】:

【参考方案4】:

我必须同意乔恩的观点。

但是,在某些情况下,我有时将受保护的变量用于“最***”继承类。例如,如果您有一个只读对象并且您无法将其设置回来但您可以在子类中使用它,我不明白为什么我应该拥有一个受保护的 Get 来访问该变量。一个简单的受保护变量做同样的封装,因为你不能设置这个变量,你只能从子类中访问这个变量。

但是设置/获取是其他情况的方法。

【讨论】:

它没有相同的封装 - 它指定现在和永远,该数据将存储在具有该名称的字段中。对该实施决策的任何更改都是重大更改。通常可以忍受这样,但我不喜欢:) 是的,Getter 的名字也是如此;)我不喜欢,但我认为在某些情况下这样做并没有那么邪恶;) 我认为 getter 的名称是 API 的一部分,然而 - 而存储的选择是一个实现问题。

以上是关于c# 使用基类中的 setter 或 getter的主要内容,如果未能解决你的问题,请参考以下文章

如果该属性在派生类中被覆盖,如何调用基类的属性?

SQLAlchemy:声明性 Mixin 类中的 getter/setter

是否使用 getter 和 setter 将消息从父 UIViewController 传递到 UIView 类中的方法?

如何为python类中的私有属性编写getter-setter方法?

类中是不是定义了 GET 或 SET

在超类中使用描述符以避免子类中的代码重复