When I run C# code through the debugger, calculated property values always seem to be displayed when I inspect an object.
e.g.
I am wondering if this is only done in the debugger, or if .Net does this as an optimization and can detect when a property changes, because this would affect how I use and access such properties to avoid performing calculations multiple times.
I have never seen it not display the value in the debugger even with complex calculations.
The debugger is calling .ToString() on all the objects. Whatever code is implemented in that function for each object is executed, which may mean it looks like the debugger has some insider information, but it really doesn't.
You can confirm this by writing your own .ToString() function in a class and see what happens.
The value of your auto-property will be computed when something calls the getter. It just so happens that the debugger will call the getter to display the property value, which is what you are seeing.
I am wondering if ... .Net does this as an optimization and can detect when a property changes, because this would affect how I use and access such properties to avoid performing calculations multiple times.
There is no built-in property value caching. Since the get method will be executed whenever you "get" the property, the calculation will be executed every time. If you want to cache the value, you could add a backing field, but you'll need to detect if/when to recalculate the value. One way would be to add logic to the setter of Value to either invalidate the cache or recompute the dependent properties (like MessageCode) at that time.
My opinion is that such a simple calculation is safe to run millions of times rather then adding the overhead of change detection.
Related
What is the difference? To me they seem very similar... Why would you use one over the other?
They're similar in that they will both store the last given value & you can access them via the public property.
Difference is:
ReactiveProperty will issue an event if and only if the value has changed.
BehaviorSubject will issue an event whatever the new value may be.
In their C# code (which is open-sourced) ReacitveProperty checks equality of new value and last value; BehaviorSubject doesn't. In fact none of ISubject implementations checks the equality.
When should you use one over another?
I would use ReactiveProperty when I want callbacks only times the value has changed even though the substitution may occur more frequently. I would use BehaviourSubject when I want callbacks whenever the substitution occurred.
In most cases ReactiveProperty is more useful because generally you want to react to changes. BehaviorSubject has its own use although less common.
Other considerations:
ReactiveProperty.SetValueAndForceNotify() can be used to invoke callbacks regardless the equality.
IObservable.DistinctUntilChanged() can be used to (secondarily) introduce the equality check.
In addition to the differences mentioned in other answers is BehaviorSubject is kinda more encapsulated compared to ReactiveProperty. That is:
BehaviorSubject.Value is get only (but .OnNext(value) is still publicly available).
ReactiveProperty.Value is settable publicly.
Behaviour Subject is one of the implementations of the Subject class. It allows you to retrieve the last value that was pushed by using the outObserver.
Reactive Property is used to provide some sort notification when something happened, it's a simpler alternative to callbacks.
For example:
If you want to chain a lot of methods to an action in your game for instance the movement of an player you can use this Rective Property.
If you want to get the last value that was pushed for instance to make a combo in a fighting game you can use Behaviour Subject.
I have a method which takes an OrderedSet X of objects of type A, and an OrderedSet Y of OrderedSets of objects of type B. (Nested)
This method then returns a new OrderedSet Z of Edges based on the two sets given.
Basically, I give the method two sets, and the method gives me back a connection much like the mathematical definition of a function.
So if I want to make a bijective connection, I would have to ensure that both sets have equal size, and I do not want null objects to be present anywhere.
The problem is, these sets are going to be arbitrarily large, and what I would like to do is this :
Ensure that nothing in these sets will ever be null
Ensure that every set has the required size
What I have done to obtain what I want :
I implemented the OrderedSet as a HashSet with extra properties, and I simply check for null elements using Contains which is O(1) (I am not entirely sure if this is a good solution)
OrderedSet refuses to add null objects, but this does not change the possibility of changing the elements within the set once they are added, and setting them to null this way
I tried taking the easy way out and nested the contents of the method in a try-catch, so if something goes wrong I simply catch the error and move on, rather than having to first validate all the data passed (Assume the sets might be very huge, there is no limitation on their size) The issue with this is that it might fail at the very end, wasting computation time
I also tried making a brute force check, so basically checking every set for nulls, including the sets within the second parameter, and also checking every single set for its correct size to be expected. This would work in theory, but I feel is impractical and surely there could be a more clever solution to this problem.
What I have considered :
I have looked into Contracts, but this article shows a significant (in my opinion) decrease in performance, although it does accomplish what I am looking for (Yet still in a hacky sort of way)
I have read about non-nullable reference types that are supposed to come out in C# 8.0, which might solve the problem of having to check for null elements, but I would still be left with the issue of having to check for all the sizes of the sets involved, each time I want to make a new connection.
My goal :
To have a readable, yet efficient solution to parameter validation.
Thank you for your time, please feel free to correct me if I have said something that is not quite correct.
When a property is updated is it good practice to change other properties based on this or should you force the user to call a method directly? For example:
someObject.TodaysTotalSales = 1234.56;
Would it be OK to have the set accessor update another value say ThisYearsTotalSales or should you force the end user to do it manually.
someObject.TodaysTotalSales = 1234.56;
someObject.UpdateThisYearsTotal();
I think the best practise is to recalculate the total year consumption only when it is accessed. Otherwise if you update the TodaysTotalSales property very often, you will compute the total year count for nothing.
More generally, when you call a property setter, you don't expect a complex operation. By convention, getters and setters are expected to return almost immediately.
If your algorithm is too complex, in that case you can use a cache value to avoid a recalculation at each call; you invalidate the cache value when one of its prerequisite has changed
It depends.
Does he need to know the TotalYearsOfSales even after he updated TodaysSales?
Yes -> Provide an additional method to update someObject.UpdateThisYearsTotal(); and at the same time flag that he has not updated YearsTotal while he did update TodaysSales, so you can throw some error at the end of the process if needed
No -> Autoupdate other properties of which the values are not needed to prior to updating the TodaysSales
TL;DR: it depends
I assume you have public interface of a class in mind.
If you follow OOP Encapsulation principle to the limit, then someObject's externally visible state should be consistent with every public access, i.e. you shouldn't need any public UpdateState methods. So in this case someObject.UpdateThisYearsTotal() is a no-no. What happens internally: be it lazy recalculation, caching, private UpdateAllInternal - would not matter.
But OOP is not an icon/idol - so for performance reasons you may design program flow as you see fit. For example: deferred bulk data processing, game loop, Entity Component System design, ORMs - those systems clearly state in their docs (rarely in code contracts) the way they are supposed to be used.
Is there a convention for whether or not to use a property to calculate a value on call? For instance if my class contains a list of integers and I have a property Average, the average will possibly change when an integer is added/removed/modified from the list, does doing something like this:
private int? _ave = null;
public int Average
{
get
{
if (_ave == null )
{
double accum = 0;
foreach (int i in myList)
{
accum += i;
}
_ave = accum / myList.Count;
return (int)_ave;
}
else
{
return (int)_ave;
}
}
}
where _ave is set to null if myList is modified in a way that may change the average...
Have any conventional advantage/disadvantage over a method call to average?
I am basically just wondering what the conventions are for this, as I am creating a class that has specific properties that may only be calculated once. I like the idea of the classes that access these properties to be able to access the property vs. a method (as it seems more readable IMO, to treat something like average as a property rather than a method), but I can see where this might get convoluted, especially in making sure that _ave is set to null appropriately.
The conventions are:
If the call is going to take significantly more time than simply reading a field and copying the value in it, make it a method. Properties should be fast.
If the member represents an action or an ability of the class, make it a method.
If the call to the getter mutates state, make it a method. Properties are invoked automatically in the debugger, and it is extremely confusing to have the debugger introducing mutations in your program as you debug it.
If the call is not robust in the face of being called at unusual times then make it a method. Properties need to continue to work when in used in constructors and finalizers, for example. Again, think about the debugger; if you are debugging a constructor then it should be OK for you to examine a property in the debugger even if it has not actually been initialized yet.
If the call can fail then make it a method. Properties should not throw exceptions.
In your specific case, it is borderline. You are performing a potentially lengthy operation the first time and then caching the result, so the amortized time is likely to be very fast even if the worst-case time is slow. You are mutating state, but again, in quite a non-destructive way. It seems like you could characterize it as a property of a set rather than an "ability" of the set. I would personally be inclined to make this a method but I would not push back very hard if you had a good reason to make it a property.
Regarding your specific implementation: I would be much more inclined to use a 64 bit integer as the accumulator rather than a 64 bit double; the double only has 53 bits of integer precision compared to the 64 bits of a long.
Microsoft's recommendation to using methods:
Use method
If calling has side effects
If it returns different values each calls
If it takes long time to call
If operation requires parameters (except indexers)
Use property if calculated value is attribute of object.
In your case I think property with implicit lazy calculation would be good choice.
Yes there is... a get accessor should not in any way modify the state of the object. The returned value could be calculated of course, and you might have a ton of code in there. But simply accessing a value should not affect the state of the containing instance at all.
In this particular case, why not calculate everything upon construction of the class instance instead? Or provide a dedicated method to force the class to do so.
Now I suppose there might be very specific situations where that sort of behavior is OK. This might be one of those. But without seeing the rest of the code (and the way it is used), it's impossible to tell.
I'm a little confused about when exactly my Property is being initialized.
Suppose I have a property declared like this:
private Dictionary<string, Dictionary<string,string>> MessageLookup
{
get
{
return messages ?? doSomething();
}
}
The doSomething method populates the messages Dictionary and returns it.
My question is, when is this code run?
If I place a breakpoint into the doSomething code, it isn't hit, but the MessageLookup property is holding data (this is the only place it is initialized) when I view it in the debugger.
Is this code run at construction? does the debugger run it automatically when I hover over the variable name? If so, why isn't the breakpoint hit?
That code is run whenever anyone refers to the property, and not before.
If you use the debugger, you'll see it because the debugger tries to fetch property values automatically (so you can see the state of the object). I don't know whether the debugger ignores breakpoints while it's evaluating properties for itself - that would explain everything.
Try running your code not in a debugger, and make some code access your property:
var lookup = someObject.MessageLookup;
Make doSomething() dump a stack trace and you'll see what's going on.
It is run when your property is first evaluated. No background stuff going on.
I'm guessing you're not seeing this because you use Quickwatch to inspect your object. At that point it will get executed and your breakpoint will be skipped.
Property getters (and ToString() for that matter) are assumed to be pure, which basically means evaluating it has no side effects. You should rewrite the code to adhere to that assumption or you'll face nasty consequences. If must use lazy initialization at access time, use a GetMessageLookup() method instead.