为什么c#属性getter不能从数据库中读取?
本文关键字:数据库 读取 不能 属性 getter 为什么 | 更新日期: 2023-09-27 18:02:35
这个问题的一些答案和注释:最简单的c#代码轮询属性?,这意味着在属性的getter中从数据库中检索数据通常是一个坏主意。
为什么这么糟糕?
(如果你有信息来源,请注明)
如果影响您的答案,我通常会将信息存储在第一个"get"之后的变量中以供重用。
因为从数据库中检索数据可能会导致任意数量的异常,而属性getter通常不应该抛出异常。
属性getter的预期行为只是返回一个值;如果它实际做的远不止这些,它应该是一个方法。
微软的属性设计指南解释了原因:https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/property
这是不好的,因为(除其他外)它违反了最小惊讶原则。
程序员通常希望属性执行简单的get/set操作。将数据访问封装在属性中可能引发异常、导致副作用并更改数据库中数据的状态,这不是通常所期望的。我并不是说没有复杂属性的情况-有时,它可能是一个很好的解决方案。但是,这不是期望的做事的方式。
简而言之:让属性getter直接访问数据库将违反关注点分离原则。
更详细: 一般来说,属性用于表示与对象相关的数据,例如Person
对象的FirstName
属性。属性值可以在内部或外部设置,但是修改和检索对象上的数据的行为应该与检索或提交该数据到永久存储的行为分开。
每次访问getter时,都要对数据库进行另一次调用。
根据定义,getter应该只是封装数据,而不是功能。
另外,如果您有多个需要往返数据库的getter,则可能需要重新定义功能并多次访问数据库。为什么不在一个集中的地方处理它,而不是将它分散到多个属性中?
方法用于类级数据修改和功能,属性仅用于单个数据修改和检索。
除了可能出现异常之外,查询数据库是一个很慢的操作。在这两个方面,使用属性获取器作为数据库访问器违反了客户端代码最少惊讶的原则。如果我看到一个带有属性的库类,我不期望它做很多工作,而是访问一个容易检索的值。
这里最不令人惊讶的选项是提供一个老式的、简单的Get函数。如果您确实只是从数据库中检索值,而不写回它的值,例如只读属性,那么本质上没有什么问题。特别是如果属性没有父属性就无法存在。然而,在实现中,它可能导致可维护性问题。您将检索存储信息的过程与对该信息的访问耦合在一起。如果对其他属性和存储系统的各个方面继续遵循此模式进行更改,则更改可能会扩散到整个代码库。例如,表名或列数据类型更改。这就是为什么在你的属性getter中有数据库调用是不好的。
附带说明:如果当您尝试检索值时数据库抛出异常,那么显然您的代码(或调用客户端的代码)中存在错误,并且无论您将数据访问代码放在何处,异常仍然会出现。很多时候,数据是由类中可能抛出异常的某种集合支持的,以这种方式存储属性值是标准做法(参见EventHandlerList)。
属性是专门设计的,因为程序员需要在获取和设置值时执行额外的逻辑,例如验证。
说了这么多,重新检查你的代码,问问你自己"以后修改它有多容易?"从那里你应该走在更容易维护的解决方案的路上。