开发者

Why should a C# property getter not read from a DB?

开发者 https://www.devze.com 2023-03-20 14:25 出处:网络
Some of the answers and comments to this question: Simplest C# code to poll a property?, imply that retrie开发者_C百科ving data from a database in a property\'s getter is Generally a Bad Idea.

Some of the answers and comments to this question: Simplest C# code to poll a property?, imply that retrie开发者_C百科ving data from a database in a property's getter is Generally a Bad Idea.

Why is it so bad?

(If you have sources for your information, please mention them.)


I will usually be storing the information in a variable after the first "get" for reuse, if that influences your answer.


Because retrieving data from a database could cause any number of exceptions, and property getters, as a rule, should never throw exceptions.

The expected behavior of a property getter is just to return a value; if it's actually doing a lot more than that, it should be a method.

Microsoft's guide for Property Design explains the reasons: https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/property


It's bad because (among other things) it violates the Principle of Least Astonishment.

Programmers generally expect properties to do simple gets/sets. Encapsulating data access in a property, which could throw exceptions, cause side effects, and change the state of the data in the database, is not what is generally expected.

I'm not saying there is no case for complex properties - sometimes, it can be a good solution. But, it is not the expected way to do things.


The Short Version: Making a property getter directly access a database would violate The Separation of Concerns principle.

More Detail: Generally speaking, a property is intended to represent data associated with an object, such as the FirstName property of a Person object. Property values may be set internally or externally, but the act of modifying and retrieving this data on the object should be separated from the act of retrieving or committing that data to a permanent store.


Any time you accessed the getter, you'd be making another call out to your database.


A getter, by definition, should just be encapsulating data, not functionality.

Also, you would likely be redefining functionality and making many trips to the database if you had more than one getter that needed to round-trip to the database. Why not handle that in a centralized place rather than splitting that out among multiple properties?

Methods are for class-level data modification and functionality, properties are for individual data modification and retrieval only.


Besides exceptions being likely, querying a database is a slooooow operation. In both aspects, using property getters as a database accessor violates the principle of least astonishment to client code. If I see a library class with a property, I don't expect it to do a lot of work, but to access a value that's easily retrieved.

The least astonishing option here is to provide an old fashioned, simple Get function.


If you are indeed only retrieving the value from the database and not also writing its value back, such as a read only property, there is nothing inherently wrong. Especially if the property cannot exists without its parent. However in implementation it can cause maintainability problems. You are coupling the process of retrieving stored information with access to that information. If you continue to follow this pattern for other properties, and aspects of your storage system change, the change could proliferate throughout your code base. For example a table name or column data type change. This is why it is bad to have database calls in your property getter.

On a side note: if the database is throwing exceptions when you try to retrieve the value, then obviously there is a bug in your code (or the calling client's code) and the exception will still surface regardless of where you put the data access code. Many times data is backed by some sort of collection within the class that can throw exceptions and it is standard practice to store property values in this manner (see EventHandlerList).

Properties were designed specifically because programmers need to perform additional logic when getting and setting values, such as validation.

With all of that having been said, reexamine your code and ask yourself "how easy will this be to change later?" from there you should be on your way to a more maintainable solution.

0

精彩评论

暂无评论...
验证码 换一张
取 消