[Rewritten 9/30/2009 to correct major misunderstanding on my part.]
You are correct. Let's look at why, first by seeing how the property set logic works and then by interpreting your experience.
How It Works
I peeked at the implementation for v.5.2.2 and here is what I see.
There are three potential groups of actions:
(1) pre-set interceptor actions,
(2) the actions DevForce performs related to setting the property value,
(3) post-set interceptor actions.
You can write interceptors that become actions in groups #1 and #3. DevForce owns group #2.
After each interceptor, DevForce checks to see if you canceled. If you did, all property set processing quits at that point. If you set cancel in a pre-set interceptor, none of the remaining pre-set interceptors nor the Group #2 and #3 actions will be performed; the property value will not change.
When you had a guard interceptor in the pre-set group that canceled because the incoming value matched the current value, the property set would bail out after completing the pre-set Group #1, before entering Group #2.
Group #2 is where DevForce potentially updates the property value. If there is no difference between the current and the incoming value, DevForce does not touch the current value, it does not change the EntityState, it won't raise PropertyChanged ... and it won't touch the Cancel flag either.
The way I read the code, no matter what DevForce does in Group #2, it will not touch the "Cancel" flag; that flag belongs to you and your interceptor chain.
My understanding is that you cannot affect what happens in Group #2. I'm a little fuzzy on this but it seems to be so even, for example, if the property fails validation. I'm prepared to be wrong about this; why would we bother checking the Cancel flag before entering Group #3 if it couldn't be changed in Group #2? I don't know as I write this.
For now you should assume that the Canceled flag will always be false coming out of Group #2 as it surely will be in your example.
DevForce, having processed Group #2, proceeds unhindered to Group #3 post-set actions.
For what it's worth, I agree with the way we do this today. I think it is correct to process post-set interceptors even if the property value is not changed. We don't know what you want to do post-set. You might want to take some action whether or not the property value changed. Maybe you want to log the attempt to change. We shouldn't guess.
What Happened To You
I'm betting you removed that guard interceptor - the one you called "BeforeSettingAnyPropertyCheckToNotDirtyForNoReason". Therefore, there was nothing to set the Canceled flag to true before it got to the post-set interceptor action group.
The Canceled flag was false upon entering the Group #3 post-set interceptor actions and your post-set interceptors were invoked.
If you don't want to process post-set interceptors, you should put guard logic in them.
Edited by WardBell - 30-Sep-2009 at 1:02pm