Today, I came across an interesting method of implementing the INotifyPropertyChanged interface. Instead of passing a string name of the property changed, or a lambda expression, we can simply call RaisePropertyChanged(); from the setter, mark that the call is parameterless. This is the code in the RaisePropertyChanged() method:
public virtual void RaisePropertyChanged()
{
var frames = new System.Diagnostics.StackTrace();
for (var i = 0; i < frames.FrameCount; i++)
{
var frame = frames.GetFrame(i).GetMethod() as MethodInfo;
if (frame != null)
if (frame.IsSpecialName && frame.Name.StartsWith("set_"))
{
RaisePropertyChanged(frame.Name.Substring(4));
return;
}
}
throw new InvalidOperationException("NotifyPropertyChanged() can only by invoked within a property setter.");
}
And this is a property that will notify its dependants of its change:
public string MyProperty
{
get { return _myField; }
set
{
_myField= value;
RaisePropertyChanged();
}
}
While I find this approach interesting, I think the performance penalty could be serious in case the property changed often... or if every property in our application used this approach to notify of its change.
I'd like to hear your opinions. (there is no longer the community-wiki checkbox?)
Would this approach be very inefficient?
Source: Article where this approach is presented
I just tested it using this code. (Note that I circumvented the limitation pointed out in Wim Coenen's answer using the MethodImpl attribute. I have my doubts as to whether this is a surefire workaround.)
Results:
Raised event using reflection 1000 times in 25.5334 ms.
Raised event WITHOUT reflection 1000 times in 0.01 ms.
So you can see, the solution involving the stack trace has about 2,500 times the cost of the "normal" solution.
That's the proportional answer, anyway. I personally dislike this idea (clever though it may be) for reasons quite beyond performance issues alone; but, obviously, it's your call.
Edit: For the record, I felt compelled to write a blog post about this—in particular, about the fact that some developers would be tempted to use an approach like this in spite of the performance hit.
Whether you agree with my feelings on the subject or not (I realize that the performance hit is small in absolute terms), I feel that the real killing blow to this idea is that, for it to be even remotely robust, it is necessary to decorate every property setter from which you intend to call RaisePropertyChanged with the MethodImpl attribute, passing MethodImplOptions.NoInlining... which, right there, negates whatever typing savings you otherwise gained.
So you're left with a net loss in development time (by however many seconds it took you to type out the whole MethodImpl attribute part), plus a performance penalty. Very little reason to go this route, if you ask me.
Yeesh, this seems like a lot of work, it'll be slow, and you run the risk of getting the method inlined.
If you want to do this, I'd suggest putting a [MethodImplAttribute] that says not to inline.
My suggestion would be to use a DynamicProxy instead as it'll be much easier and much faster than this approach, the only downside is you must specify the method as virtual. For instance in my work in progress proxy I specify a metaprogramming definition and bind it for my properties, here is my NotifyPropertyChanged interceptor.
private static void SetterInterceptor<T, TProperty>(ProxiedProperty<T, TProperty> property, T target, TProperty value) where T:class,IAutoNotifyPropertyChanged
{
TProperty oldValue;
if (!EqualityComparer<TProperty>.Default.Equals(oldValue = property.GetMethod.CallBaseDelegate(target), value))
{
property.SetMethod.CallBaseDelegate(target, value);
target.OnPropertyChanged(new PropertyChangedEventArgs(property.Property.Name));
}
}
Then it's just a foreach loop across the properties I'm interested in with calls to Delegate.CreateDelegate to perform the binding.
I have no clear proofs, but I believe yes, it would be very costly, especially if every property does this.
Performance doesn't matter, because the linked article states that it doesn't really work:
Apparently this is a method that has
been tried in the past. As Sergey
Barskiy pointed out, the JITter will
likely inline the method and break the
stack frame.
A different approach that I like better is here:
You can get the property name using
reflection on a lambda function that
calls the property getter.
How to raise PropertyChanged event without using string name
Related
To synchronize the access to my properties I use the ReaderWriterLockSlim class. I use the following code to access my properties in a thread-safe way.
public class SomeClass
{
public readonly ReaderWriterLockSlim SyncObj = new ReaderWriterLockSlim();
public string AProperty
{
get
{
if (SyncObj.IsReadLockHeld)
return ComplexGetterMethod();
SyncObj.EnterReadLock();
try
{
return ComplexGetterMethod();
}
finally
{
SyncObj.ExitReadLock();
}
}
set
{
if (SyncObj.IsWriteLockHeld)
ComplexSetterMethod(value);
else
{
SyncObj.EnterWriteLock();
ComplexSetterMethod(value);
SyncObj.ExitWriteLock();
}
}
}
// more properties here ...
private string ComplexGetterMethod()
{
// This method is not thread-safe and reads
// multiple values, calculates stuff, ect.
}
private void ComplexSetterMethod(string newValue)
{
// This method is not thread-safe and reads
// and writes multiple values.
}
}
// =====================================
public static SomeClass AClass = new SomeClass();
public void SomeMultiThreadFunction()
{
...
// access with locking from within the setter
AClass.AProperty = "new value";
...
// locking from outside of the class to increase performance
AClass.SyncObj.EnterWriteLock();
AClass.AProperty = "new value 2";
AClass.AnotherProperty = "...";
...
AClass.SyncObj.ExitWriteLock();
...
}
To avoid unnecessary locks whenever I get or set multiple properties a once I published the ReaderWriterLockSlim-Object and lock it from outside of the class every time I'm about to get or set a bunch of properties. To achieve this my getter and setter methods check if the lock has been acquired using the IsReadLockHeld property and the IsWriteLockHeld property of ReaderWriterLockSlim. This works fine and has increased the performance of my code.
So far so good but when I re-read the documentation about IsReadLockHeld and IsWriteLockHeld I noticed the remark form Microsoft:
This property is intended for use in asserts or for other debugging
purposes. Do not use it to control the flow of program execution.
My question is: Is there a reason why I should not use IsReadLockHeld/IsWriteLockHeld for this purpose? Is there anything wrong with my code? Everything works as expected and much faster than using recursive locks (LockRecursionPolicy.SupportsRecursion).
To clarify this up: This is a minimal example. I don't want to know if the lock itself is necessary or can be removed or achieved in a different way. I just want to know why I should not use IsReadLockHeld/IsWriteLockHeld to control the flow of the programm as stated by the documentation.
After some further research I posted the same question on the German Support Forum of the Microsoft Developer Network and got into discussion with the very helpful moderator Marcel Roma. He was able to contact the programmer of the ReaderWriterLockSlim Joe Duffy who wrote this answer:
I'm afraid my answer may leave something to be desired.
The property works fine and as documented. The guidance really is just
because conditional acquisition and release of locks tends to be buggy
and error-prone in practice, particularly with exceptions thrown into
the mix.
It's typically a good idea to structure your code so that you either
use recursive acquires, or you don't, (and of course the latter is
always easier to reason about); using properties like IsReadLockHeld
lands you somewhere in the middle.
I was one of the primary designers of RWLS and I have to admit it has
way too many bells and whistles. I don't necessarily regret adding
IsReadLockHeld -- as it can come in handy for debugging and assertions
-- however as soon as we added it, Pandora's box was opened, and we RWLS was instantly opened up to this kind of usage.
I'm not surprised that people want to use it as shown in the
StackOverflow thread, and I'm sure there are some legitimate scenarios
where it works better than the alternatives. I merely advise erring on
the side of not using it.
To sum things up: You can use the IsReadLockHeld and the IsWriteLockHeld property to acquire a lock conditionally and everything will work fine, but it is bad programming style and one should avoid it. It is better to stick to recursive or non-recursive locks. To maintain a good coding style IsReadLockHeld and IsWriteLockHeld should only be used for debugging purposes.
I want to thank Marcel Roma and Joe Duffy again for their precious help.
Documentation is advising you the right thing.
Considere the following interleaved execution.
Thread1.AcqrireReadLock();
Thread1.ComplexGetterMethod();
Thread2.ReadIsReaderLockHeldProperty();
Thread1.ReleaseReadLock();
Thread2.ComplexGetterMethod(); // performing read without lock.
The other wrong thing with your code that I see is
SyncObj.EnterReadLock();
try
{
return ComplexGetterMethod();
}
finally
{
SyncObj.ExitReadLock();
}
is not the right way to do things. This is one right:
try
{
SyncObj.EnterReadLock();
return ComplexGetterMethod();
}
finally
{
if (SyncObj.IsReadLockHeld)
SyncObj.ExitReadLock();
}
And this shall be exact definition of your getter method.
In C# (or VB .NET), does the compiler make attempts to optimize property accesses? For eg.,
public ViewClass View
{
get
{
...
Something is computed here
....
}
}
if (View != null)
View.Something = SomethingElse;
I would imagine that if the compiler could somehow detect that View remains constant between the two accesses, it can refrain from computing the value twice. Are these kind of optimizations performed?
I understand that if View has some intensive computations, it should probably be refactored into a function (GetView()). In my particular case, View involves climbing the visual tree looking for an element of a particular type.
Related: Any references on the workings of the (Microsoft) C# compiler?
Not in general, no. As Steven mentioned there are numerous factors to consider regarding multithreading, if you truly are computing something that might change, you're correct it should be refactored away from a property. If it won't change, you should lazy-load it (check if the private member is null, if so then calculate, then return the value).
If it won't change and depends on a parameter, you can use a Dictionary or Hashtable as a cache - given the parameter (key) you will store the value. You could have each entry as a WeakReference to the value too, so when the value isn't referenced anywhere and garbage collection happens, the memory will be freed.
Hope that helps.
The question is very unclear, it isn't obvious to me how the getter and the snippet below it are related. But yes, property accessors are normally heavily optimized. Not by the C# compiler, by the JIT compiler. For one, they are often inlined so you don't pay for the cost of a method call.
That will only happen if the getter doesn't contain too much code and doesn't monkey with locks and exception handling. You can help the JIT compiler to optimize the common case with code like this:
get
{
if (_something == null) {
_something = createSomething();
}
return _something;
}
This will inline the common case and allow the creation method to remain un-inlined. This gets typically compiled to three machine code instructions in the Release build (load + test + jump), about a nano-second of execution time. It is a micro-optimization, seeing an actual perf improvement would be quite rare.
Do note that the given sample code is not thread-safe. Always write correct code rather than fast code first.
No, which is why you should use Lazy<T> to implement a JIT calculation.
From my understanding there is no implicit caching - you have to cache the value of a given property yourself the first time it is calculated
For example:
object mCachedValue = null;
public Object MyProperty
{
get
{
if (mCachedValue == null)
{
lock(mCachedValue)
{
//after acquiring the lock check if the property has not been initialized in the mean time - only calculate once
if (mCachedValue == null)
{
//calculate value the first time
}
}
}
return mCachedValue;
}
In classes that implement INotifyPropertyChanged I often see this pattern :
public string FirstName
{
get { return _customer.FirstName; }
set
{
if (value == _customer.FirstName)
return;
_customer.FirstName = value;
base.OnPropertyChanged("FirstName");
}
}
Precisely the lines
if (value == _customer.FirstName)
return;
are bothering me. I've often did this but I am not that sure it's needed nor good. After all if a caller assigns the very same value I don't want to reassign the field and, especially, notify my subscribers that the property has changed when, semantically it didn't.
Except saving some CPU/RAM/etc by freeing the UI from updating something that will probably look the same on the screen/whatever_medium what do we obtain?
Could some people force a refresh by reassigning the same value on a property (NOT THAT THIS WOULD BE A GOOD PRACTICE HOWEVER)?
1. Should we do it or shouldn't we?
2. Why?
Yes, you should return immediately when the consumer is setting a property value that is equal to the value which is already being persisted.
First of all, there is no reason to waste any time or resources in the setter of the property - the value is already set so no further action is needed. Also you should never call OnPropertyChanged if the value stored in the property's backing field hasn't changed - the method is intended to be raised when the value has changed not when the property's setter has been called.
All that being said, however - if the setter didn't have a call to OnPropertyChanged I wouldn't have bothered to check the value first. In the case of a simple setter that only sets the backing field's value and nothing else it is actually going to be faster to always the set the value rather than checking first then setting the value. Only use this pattern when the property's setter has additional logic that either shouldn't fire or may incur an unnecessary performance penalty.
Or you could do this:
set
{
if (value != _customer.FirstName)
{
_customer.FirstName = value;
base.OnPropertyChanged("FirstName");
}
}
No need for multiple return paths.
To further answer your question, I wouldn't force an update to property if it's being overwritten by the same value. There's really no point, because you're probably not going to get any benefit from it. (I could see an instance where you would want to track each time someone tries to update a value.)
The only argument against that pattern (where you return if the value hasn't changed) I can think of is the purist's view that every function should have only one exit. Not being a purist, I don't agree. I see nothing wrong with breaking out if the value hasn't changed, avoiding the notification update.
The only situation when you shouldn't use it is when you know that you can have dirty data on your class, for example on a ORM layer object that might have outdated values compared to the underlying database because of modification by another user.
If that situation doesn't affect you, then cache away!
Edit
I misunderstood your question, as you are talking about setters, not getters.
Similar points apply. If the set operation is a costly one, and is not supposed to have any kind of side effect (it should't! Side effects on setters are <blink>evil</blink>!!1), then it's a valid optimization.
One reason to not return early, I would imagine, is for subscribers that joined the party late. They might not be aware of the object's current state, and will miss out on the setter notification if you return early.
Most of times those properties are used in binding. But as soon as you start using NotifyPropertyChanged event yourself (in own markup extenstions, behaviors, between VM in MVVM, etc.) you will realise you just want this event to always occurs.
To me this check (notification protection) is kind of premature optimization. I am often rising event with "" as propertyName to just refresh bindings or force event for some custom stuff and that alone is much more costly.
I don't see a need to protect each property. Why? From what kind of operation? Animations are running on dependency properties. User updates (when view bindings are updating source) are anyway slow. And for any update rised from within code behind you are pretty much need event to be rised.
To me it looks like a pattern, invented without much reasons and followed blindly. Of course there are cases when you need to prevent property setter code from being running under certain conditions. And that's ok if you add such checks to solve certain performance issue then. But not in advance.
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.
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.