c# - C# 中的 getter 和 setter 有哪些更好的替代方法?

标签 c# oop accessor

我已经阅读了一些关于在面向对象编程中使用 getter/setter 的内容以及许多资源,例如 this建议不要经常使用它们。该文章的引述说:

Don't ask for the information you need to do the work; ask the object that has the information to do the work for you.

虽然这在原则上听起来不错,但我并不是特别确定如何最好地实现它。比如说我有一个描述汽车的类(class)。在那个类中,假设类中存储的这辆车的品牌是“Toyota”。现在我有一个 GUI 想要显示这是一辆“丰田”。如果没有 setter/getter ,如何做到这一点?

即使我抽象出“Toyota”存储为字符串并返回其中已写入“Toyota”的 TextBox,这听起来充其量只是原始属性的包装形式的 getter。我只是认为像 TextBoxes 这样的东西应该只在 GUI 的类中,而不是像我这里的汽车类这样的辅助类。

最佳答案

那篇文章描述了您应该使用方法而不是属性 getter/setter。基本上它建议一个方法应该执行一个操作来修改状态,而不是允许 setter 修改状态。例如我可以有一个带有 Month 和 Day 属性的类。然后我可以使用代码来执行此操作:

obj.Day = 28;
obj.Month = Months.February;
obj.Day = 30;
obj.Month = Months.March;

只要我将一天设置为 30,而月份是二月,我的状态就会无效。

文章建议一个类不应该允许这种类型的事情,而是提供特定的方法来执行特定的操作,比如:

obj.ChangeDate(Months.March, 30);

如果日期时间类比由于 DateTime 而令人困惑,您可以使用经/纬度坐标来举一个类似的例子:

obj.Latitude = 45.4112;
obj.Longitude = -75.6981;
//... 
obj.Latitude = 39.73;
obj.Longitude = -86.27;

当纬度设置为 39.73 时,位置变为靠近纽瓦克的地方,而不是渥太华(第一个纬度/经度)或印第安纳波利斯(第二个纬度/经度)。保留纬度/经度的设置会使界面开放,无法验证其不变量,有些人可能会说不是真正的面向对象。因此,您可能有一个方法:

obj.MoveTo(39.73, -86.27);

OO 意味着封装的状态和行为。虽然有些人可能认为属性“封装”了状态,但它们通常不会。它们将实现与接口(interface)分离,以便可以更改用作属性后备存储的内容——但是,它很少这样做;所以这些属性只是提供可用的实现细节,而不是提供公共(public)字段。

命令查询分离等概念建立在这个想法的基础上,建议接口(interface)应该更新状态或查询状态,但不能同时更新。同时具有 getter 和 setter 的属性提供了一个既可以更新状态又可以查询状态的接口(interface)。上面的示例 MoveToChangeDate 将是“命令”。从概念上讲,您将提供其他查询状态的方法;如果需要的话。

属性的另一个问题是人们习惯性地同时添加 getter 和 setter,因为它是一个属性。获取或设置属性的能力可能不是必需的,只需通过机械创建和接口(interface)添加 getter 和 setter,这可能永远不需要测试和维护。

微妙?当然;但他说的是面向对象的设计,而不是“正常工作”的代码。

关于c# - C# 中的 getter 和 setter 有哪些更好的替代方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12187232/

相关文章:

javascript - D3.js 中的 array_replace?

c# - VB.NET 和 C# 可见性中的静态/共享

c# - 将异常冒泡到堆栈顶部是否可以?

c# - 使用distinct删除重复项

c#接口(interface),抽象类,强制继承类不是抽象类

php - 将树状对象结构转换为数组并交互整个事物

c# - 当接口(interface)中有重载方法时,为什么我的代码会调用错误的方法

c# - 在不使用 MediaTypeWithQualityHeaderValue 的情况下设置接受 header

c# - 具有默认实现的接口(interface)和抽象类之间有什么区别?

javascript - for-in 循环 VS in-operator