When databinding my xaml to some data I often use the "get" part of a property to do some logic. Like giving to sum of totals of a list or a check if something is positive.
For example:
public List<SomeClass> ListOfSomeClass{get;set;}
public double SumOfSomeClass
{
get
{
return ListOfSomeClass.Sum(s => s.Totals);
}
}
public bool SumPositive
{
get
{
if(SumOfSomeClass >= 0)
return true;
else
return false;
}
}
This way I can bind to SumPositive and SumOfSomeClass. Is this considered good practice? Even if it gets more complex than this? Or would it be better call a method and return the outcome? What about calls to another class or even a database?
Property getters are expected to be fast and idempotent (i.e. no destructive actions should be performed there). Though it's perfectly fine to iterate over an in-memory collection of objects, I wouldn't recomment doing any kind of heavy lifting in either get or set parts. And speaking of iterating, I'd still cache the result to save a few milliseconds.
Yes, unless it is an operation that might have performance implications. In that case you should use a method instead (as it is more intuitive to the end user that a method might be slow whereas a property will be quick)
I like your naming conventions and I agree entirely with using content such as your example in property getters, if you're delivering an API to be used with binding.
I don't agree with the point others have made about moving code into a method just because it is computationally heavy - that's not a distinction I'd ever make nor have I heard other people suggest that being in a method implies slower than a property.
I do believe that properties should be side-effect-free on the object on which they are called. It's vastly more difficult to guarantee they have no effect on the broader environment - even a relatively trivial property might pull data into memory or at least change the processor cache or vm state.
I say yes, but try to store on a private variable de results of ListOfSomeClass.Sum(s => s.Totals). Specially if you use it more than once.
I don't see any direct issue (unless the list is quite huge) but I would personally use the myInstance.SomeList.Sum() method if possible (.net >= 2.0).
For basic calculations off of fields or other properties in the collection it would be acceptable to do that inside the Get property. As everyone else said true logic should never be done in the getter.
Please change that getter to this:
public bool SumPositive
{
get
{
return SumOfSomeClass >= 0;
}
}
You are already using a boolean expression, no need to explicitly return true or false
Having complex logic in getters/setters is not a good practice. I recommend to move complex logic to separate methods (like GetSumOfXYZ()) and use memoization in property accessors.
You can avoid complex properties by using ObjectDataProvider - it allows you to define method to pull some data.
Depends... if this was on a domain entity then I wouldn't be in favor having complex logic in a getter and especially not a setter. Using a method (to me) signals a consumer of the entity that an operation is being performed while a getter signals a simple retrieval.
Now if this logic was in a ViewModel, then I think the getter aspect is a little more forgivable / expected.
I think that there is some level of logic that is expected in Getters and Setters, otherwise you just have a kind of convoluted way to declare your members public.
I would be careful about putting any logic in the Getter of a property. The more expensive it is to do, the more dangerous it is. Other developers expect a getter to return a value immediately just like getting a value from a member variable. I've seen a lot of instances where a developer uses a property on every iteration of a loop, thinking that they are just getting back a value, while the property is actually doing a lot of work. This can be a major slowdown in your code execution.
Related
When I first began as a junior C# dev, I was always told during code reviews that if I was accessing an object's property more than once in a given scope then I should create a local variable within the routine as it was cheaper than having to retrieve it from the object. I never really questioned it as it came from more people I perceived to be quite knowledgeable at the time.
Below is a rudimentary example
Example 1: storing an objects identifer in a local variable
public void DoWork(MyDataType object)
{
long id = object.Id;
if (ObjectLookup.TryAdd(id, object))
{
DoSomeOtherWork(id);
}
}
Example 2: retrieving the identifier from the Id property of the object property anytime it is needed
public void DoWork(MyDataType object)
{
if (ObjectLookup.TryAdd(object.Id, object))
{
DoSomeOtherWork(object.Id);
}
}
Does it actually matter or was it more a preference of coding style where I was working? Or perhaps a situational design time choice for the developer to make?
As explained in this answer, if the property is a basic getter/setter than the CLR "will inline the property access and generate code that’s as efficient as accessing a field directly". However, if your property, for example, does some calculations every time the property is accessed, then storing the value of the property in a local variable will avoid the overhead of additional calculations being done.
All the memory allocation stuff aside, there is the principle of DRY(don't repeat yourself). When you can deal with one variable with a short name rather than repeating the object nesting to access the external property, why not do that?
Apart from that, by creating that local variable you are respecting the single responsibility principle by isolating the methods from the external entity they don't need to know about.
And lastly if the so-called resuing leads to unwanted instantiation of reference types or any repetitive calculation, then it is a must to create the local var and reuse it throughout the class/method.
Any way you look at it, this practice helps with readability and more maintainable code, and possibly safer too.
I don't know if it is faster or not (though I would say that the difference is negligible and thus unimportant), but I'll cook up some benchmark for you.
What IS important though will be made evident to you with an example;
public Class MyDataType
{
publig int id {
get {
// Some actual code
return this.GetHashCode() * 2;
}
}
}
Does this make more sense? The first time I will access the id Getter, some code will be executed. The second time, the same code will be executed costing twice as much with no need.
It is very probable, that the reviewers had some such case in mind and instead of going into every single one property and check what you are doing and if it is safe to access, they created a new rule.
Another reason to store, would be useability.
Imagine the following example
object.subObject.someOtherSubObject.id
In this case I ask in reviews to store to a variable even if they use it just once. That is because if this is used in a complicated if statement, it will reduce the readability and maintainability of the code in the future.
A local variable is essentially guaranteed to be fast, whereas there is an unknown amount of overhead involved in accessing the property.
It's almost always a good idea to avoid repeating code whenever possible. Storing the value once means that there is only one thing to change if it needs changing, rather than two or more.
Using a variable allows you to provide a name, which gives you an opportunity to describe your intent.
I would also point out that if you're referring to other members of an object a lot in one place, that can often be a strong indication that the code you're writing actually belongs in that other type instead.
You should consider that getting a value from a method that is calculated from an I/O-bound or CPU-bound process can be irrational. Therefore, it's better to define a var and store the result to avoid multiple same processing.
In the case that you are using a value like object.Id, utilizing a variable decorated with const keyword guarantees that the value will not change in the scope.
Finally, it's better to use a local var in the classes and methods.
This is probably a matter of personal preference, but when do you use properties instead of functions in your code
For instance to get an error log I could say
string GetErrorLog()
{
return m_ErrorLog;
}
or I could
string ErrorLog
{
get { return m_ErrorLog; }
}
How do you decide which one to use? I seem to be inconsistent in my usage and I'm looking for a good general rule of thumb. Thanks.
I tend to use properties if the following are true:
The property will return a single, logic value
Little or no logic is involved (typically just return a value, or do a small check/return value)
I tend to use methods if the following are true:
There is going to be significant work involved in returning the value - ie: it'll get fetched from a DB, or something that may take "time"
There is quite a bit of logic involved, either in getting or setting the value
In addition, I'd recommend looking at Microsoft's Design Guidelines for Property Usage. They suggest:
Use a property when the member is a logical data member.
Use a method when:
The operation is a conversion, such as Object.ToString.
The operation is expensive enough that you want to communicate to the user that they should consider caching the result.
Obtaining a property value using the get accessor would have an observable side effect.
Calling the member twice in succession produces different results.
The order of execution is important. Note that a type's properties should be able to be set and retrieved in any order.
The member is static but returns a value that can be changed.
The member returns an array. Properties that return arrays can be very misleading. Usually it is necessary to return a copy of the internal array so that the user cannot change internal state. This, coupled with the fact that a user can easily assume it is an indexed property, leads to inefficient code. In the following code example, each call to the Methods property creates a copy of the array. As a result, 2n+1 copies of the array will be created in the following loop.
Here are Microsoft's guidelines:
Choosing Between Properties and Methods
Consider using a property if the member represents a logical attribute of the type.
Do use a property, rather than a method, if the value of the property is stored in the process memory and the property would just provide access to the value.
Do use a method, rather than a property, in the following situations.
The operation is orders of magnitude slower than a field set would be. If you are even considering providing an asynchronous version of an operation to avoid blocking the thread, it is very likely that the operation is too expensive to be a property. In particular, operations that access the network or the file system (other than once for initialization) should most likely be methods, not properties.
The operation is a conversion, such as the Object.ToString method.
The operation returns a different result each time it is called, even if the parameters do not change. For example, the NewGuid method returns a different value each time it is called.
The operation has a significant and observable side effect. Note that populating an internal cache is not generally considered an observable side effect.
The operation returns a copy of an internal state (this does not include copies of value type objects returned on the stack).
The operation returns an array.
I use properties when its clear the semantic is "Get somevalue from the object". However using a method is a good way to communicate "this may take a bit more than a trivial effort to return".
For example a collection could have a Count property. Its reasonable to assume a collection object knows how many items are currently held without it actually having to loop through them and count them.
On the hand this hypothetical collection could have GetSum() method which returns the total of the set of items held. The collection just a easily have a Sum property instead but by using a method it communicates the idea that the collection will have to do some real work to get an answer.
I'd never use a property if I could be affecting more than one field - I'd always use a method.
Generally, I just use the
public string ErrorLog { get; private set; }
syntax for Properties and use Methods for everything else.
In addition to Reed's answer when the property is only going to be a getter like getting a resource such as an Event Log might be. I try and only use properties when the property will be side effect free.
If there is more than something trivial happening in a property, then it should be a method. For example, if your ErrorLog getter property was actually going and reading files, then it should be a method. Accessing a property should be fast, and if it is doing much processing, it should be a method. If there are side affects of accessing a property that the user of the class might not expect, then it should probably be a method.
There is .NET Framework Design Guidelines book that covers this kind of stuff in great detail.
I tend to assume that getters are little more than an access control wrapper around an otherwise fairly lightweight set of instructions to return a value (or set of values).
As a result, when I find myself writing longer and more CPU-hungry setters, I feel Perhaps this is not the smartest move. In calling a getter in my own code (in particular let's refer to C# where there is a syntactical difference between method vs. getter calls), then I make an implicit assumption that these are lightweight -- when in fact that may well not be the case.
What's the general consensus on this? Use of other people's libraries aside, do you write heavy getters? Or do you tend to treat heavier getters as "full methods"?
PS. Due to language differences, I expect there'll be quite a number of different thoughts on this...
Property getters are intended to retrieve a value. So when developers call them, there is an expectation that the call will return (almost) immediately with a value. If that expectation cannot be met, it is better to use a method instead of a property.
From MSDN:
Property Usage Guidelines
Use a method when:
[...]
The operation is expensive enough that you want to communicate to the
user that they should consider caching
the result.the result.
And also:
Choosing Between Properties and Methods
Do use a method, rather than a
property, in the following situations.
The operation is orders of magnitude slower than a field set would be. If
you are even considering providing an
asynchronous version of an operation
to avoid blocking the thread, it is
very likely that the operation is too
expensive to be a property. In
particular, operations that access the
network or the file system (other than
once for initialization) should most
likely be methods, not properties.
True. Getters should either access a simple member, or should compute and cache a derived value and then return the cached value (subsequent gets without interleaved sets should merely return that value). If I have a function that is going to do a lot of computation, then I name it computeX, not getX.
All in all, very few of my methods are so expensive in terms of time that it would matter based on the guidelines as posted by Thomas. But the thing is that generally calls to a getter should not affect that state of the class. I have no problem writing a getter that actually runs a calculation when called though.
In general, I write short, efficient ones. But you might have complex ones -- you need to consider how the getter will be used. And if it is an external API, you don't have any control how it is used - so shoot for efficiency.
I would agree with this. It is useful to have calculated properties for example for things like Age based on DateOfBirth. But I would avoid complex logic like having to go to a database just to calculate the value of an object's property. Use method in that case.
My opinion is that getter should be lightweight, but again as you say there is a broad definition of "lightweight", adding a logger is fine for tracing purpose, and probably some cache logic too and database/web service retrieval .. ouch. your getter is already considered heavy.
Getter are syntaxic sugar like setters, I consider that method are more flexible because of the simplicity of using them asynchronously.
But there is no expectation set for your getter performance (maybe try to mention it in the cough documentation ), as it could be trying to retrieve fresh values from slow source.
Others are certainly considering getter for simple objects, but as your object could be a proxy for your backend object, I really see not point too set performance expectations as it helps you makes the code more readable and more maintainable.
So my answer would be, "it depends", mainly on the level of abstraction of your object ( short logic for low level object as the value should probably be calculated on the setter level, long ones for hight level ).
I would like to get your opinion on as how far to go with side-effect-free setters.
Consider the following example:
Activity activity;
activity.Start = "2010-01-01";
activity.Duration = "10 days"; // sets Finish property to "2010-01-10"
Note that values for date and duration are shown only for indicative purposes.
So using setter for any of the properties Start, Finish and Duration will consequently change other properties and thus cannot be considered side-effect-free.
Same applies for instances of the Rectangle class, where setter for X is changing the values of Top and Bottom and so on.
The question is where would you draw a line between using setters, which have side-effects of changing values of logically related properties, and using methods, which couldn't be much more descriptive anyway. For example, defining a method called SetDurationTo(Duration duration) also doesn't reflect that either Start or Finish will be changed.
I think you're misunderstanding the term "side-effect" as it applies to program design. Setting a property is a side effect, no matter how much or how little internal state it changes, as long as it changes some sort of state. A "side-effect-free setter" would not be very useful.
Side-effects are something you want to avoid on property getters. Reading the value of a property is something that the caller does not expect to change any state (i.e. cause side-effects), so if it does, it's usually wrong or at least questionable (there are exceptions, such as lazy loading). But getters and setters alike are just wrappers for methods anyway. The Duration property, as far as the CLR is concerned, is just syntactic sugar for a set_Duration method.
This is exactly what abstractions such as classes are meant for - providing coarse-grained operations while keeping a consistent internal state. If you deliberately try to avoid having multiple side-effects in a single property assignment then your classes end up being not much more than dumb data containers.
So, answering the question directly: Where do I draw the line? Nowhere, as long as the method/property actually does what its name implies. If setting the Duration also changed the ActivityName, that might be a problem. If it changes the Finish property, that ought to be obvious; it should be impossible to change the Duration and have both the Start and Finish stay the same. The basic premise of OOP is that objects are intelligent enough to manage these operations by themselves.
If this bothers you at a conceptual level then don't have mutator properties at all - use an immutable data structure with read-only properties where all of the necessary arguments are supplied in the constructor. Then have two overloads, one that takes a Start/Duration and another that takes a Start/Finish. Or make only one of the properties writable - let's say Finish to keep it consistent with Start - and then make Duration read-only. Use the appropriate combination of mutable and immutable properties to ensure that there is only one way to change a certain state.
Otherwise, don't worry so much about this. Properties (and methods) shouldn't have unintended or undocumented side effects, but that's about the only guideline I would use.
Personally, I think it makes sense to have a side-effect to maintain a consistent state. Like you said, it makes sense to change logically-related values. In a sense, the side-effect is expected. But the important thing is to make that point clear. That is, it should be evident that the task the method is performing has some sort of side-effect. So instead of SetDurationTo you could call your function ChangeDurationTo, which implies something else is going on. You could also do this another way by having a function/method that adjusts the duration AdjustDurationTo and pass in a delta value. It would help if you document the function as having a side-effect.
I think another way to look at it is to see if a side-effect is expected. In your example of a Rectangle, I would expect it to change the values of top or bottom to maintain an internally-consistent state. I don't know if this is subjective; it just seems to make sense to me. As always, I think documentation wins out. If there is a side-effect, document it really well. Preferably by the name of the method and through supporting documentation.
One option is to make your class immutable and have methods create and return new instances of the class which have all appropriate values changed. Then there are no side effects or setters. Think of something like DateTime where you can call things like AddDays and AddHours which will return a new DateTime instance with the change applied.
I have always worked with the general rule of not allowing public setters on properties that are not side-effect free since callers of your public setters can't be certain of what might happen, but of course, people that modify the assembly itself should have a pretty good idea as they can see the code.
Of course, there are always times where you have to break the rule for the sake of either readability, to make your object model logical, or just to make things work right. Like you said, really a matter of preference in general.
I think it's mostly a matter of common-sense.
In this particular example, my problem is not so much that you've got properties that adjust "related" properties, it's that you've got properties taking string values that you're then internaly parsing into DateTime (or whatever) values.
I would much rather see something like this:
Activity activity;
activity.Start = DateTime.Parse("2010-01-01");
activity.Duration = Duration.Parse("10 days");
That is, you explicity note that you're doing parsing of strings. Allow the programmer to specify strong-typed objects when that is appropriate as well.
This question already has answers here:
What is the best way to access properties from the same class, via accessors or directly? [closed]
(5 answers)
Closed 9 years ago.
I have a class 'Data' that uses a getter to access some array. If the array is null, then I want Data to access the file, fill up the array, and then return the specific value.
Now here's my question:
When creating getters and setters should you also use those same accessor properties as your way of accessing that array (in this case)? Or should you just access the array directly?
The problem I am having using the accessors from within the class is that I get infinite loops as the calling class looks for some info in Data.array, the getter finds the array null so goes to get it from the file, and that function ends up calling the getter again from within Data, array is once again null, and we're stuck in an infinite loop.
EDIT:
So is there no official stance on this? I see the wisdom in not using Accessors with file access in them, but some of you are saying to always use accessors from within a class, and others are saying to never use accessors from with the class............................................
I agree with krosenvold, and want to generalize his advice a bit:
Do not use Property getters and setters for expensive operations, like reading a file or accessing the network. Use explicit function calls for the expensive operations.
Generally, users of the class will not expect that a simple property retrieval or assignment may take a lot of time.
This is also recommended in Microsoft's Framework Design Guidelines.;
Do use a method, rather than a
property, in the following situations.
The operation is orders of magnitude
slower than a field set would be. If
you are even considering providing an
asynchronous version of an operation
to avoid blocking the thread, it is
very likely that the operation is too
expensive to be a property. In
particular, operations that access the
network or the file system (other than
once for initialization) should most
likely be methods, not properties.
I think its a good idea to always use the accessors. Then if you need any special logic when getting or setting the property, you know that everything is performing that logic.
Can you post the getter and setter for one of these properties? Maybe we can help debug it.
I have written a getter that opens a file and always regretted it later. Nowdays I would never solve that problem by lazy-constructing through the getter - period. There's the issue of getters with side-effects where people don't expect all kinds of crazy activity to be going on behind the getter. Furthermore you probably have to ensure thread safety, which can further pollute this code. Unit-Testing can also become slightly harder each time you do this.
Explicit construction is a much better solution than all sorts of lazy-init getters. It may be because I'm using DI frameworks that give me all of this as part of the standard usage patterns. I really try to treat construction logic as distinctly as possible and not hide too much, it makes code easier to understand.
No. I don't believe you should, the reason: maintainable code.
I've seen people use properties within the defining class and at first all looks well. Then someone else comes along and adds features to the properties, then someone else comes along and tries to change the class, they don't fully understand the class and all hell breaks loose.
It shouldn't because maintenance teams should fully understand what they are trying to change but they are often looking at a different problem or error and the encapsulated property often escapes them. I've see this a lot and so never use properties internally.
They can also be a performance hog, what should be a simple lookup can turn nasty if someone puts database code in the properties - and I have seen people do that too!
The KISS principle is still valid after all these years...!
Aside from the point made by others, whether to use an accessor or a field directly may need to be informed by semantics. Some times the semantics of an external consumer accessing a property is different from the mechanical necessity of accessing its value by internal code.
Eric Lippert recently blogged on this subject in a couple of posts:-
automatic-vs-explicit-properties
future-proofing-a-design
If using an Get method leads to this kind of error, you should access the value directly. Otherwise, it is good practice to use your accessors. If you should modify either the getter or setter to take specific actions in the future, you'll break your object if you fail to use that path.
I guess what you are trying to implement is some sort of a lazy-loading property, where you load the data only when it is accessed for the first time.
In such a case I would use the following approach to prevent the infinite loop:
private MyData _data = null;
public MyData Data
{
get
{
if (_data == null)
_data = LoadDataFromFile();
return _data;
}
}
private MyData LoadDataFromFile()
{
// ...
}
In other words:
don't implement a setter
always use the property to access the data (never use the field directly)
You should always use the accessors, but the function that reads the value from the file (which should be private, and called something like getValueFromFile) should only be called when the value has to be read from the file, and should just read the file and return the value(s). That function might even be better off in another class, dedicated to reading values from your data file.
If I am understanding it right, you are trying to access a property from within it's implementation (by using a method that calls the same property in the property's implementation code). I am not sure if there any official standards regarding this, but I would consider it a bad practice, unless there would be a specific need to do it.
I always prefer using private members within a class instead of properties, unless I need the functionality property implementation provides.