XPO Simplified property syntax - a summary

XPO Team Blog
01 February 2007

It’s been a while since we introduced a feature called “simplified property syntax” to XPO. At the time I posted some information about it to the newsgroup, but there have been developments, changes and inconsistent statements about the whole topic, so I thought it would be good to summarize the information in one place.

So what is that simplified syntax we’re talking about? That’s rather easy: we have introduced a number of helper methods in our XPBaseObject class, which allow you to use a shorter form for property implementations. We have previously recommended a certain form for property implementations in persistent classes – see this article, the section titled “Automatic collection of changes” – and this new simplified form takes care of the notification requirement described in that article while providing a concise syntax at the same time.

There are several use cases of the helper functionality we provide, and I want to describe each of them on its own.

Case 1 – automatic value storage, simple syntax – not recommended

public class Person : XPObject {
  ...

  public DateTime Birthday {
    get { return GetPropertyValue<DateTime>(); }
    set { SetPropertyValue(value); }
  }

  ...
}

Now, I’m sure this is very close to the shortest form anybody can imagine for a property implementation. Originally we were planning to recommend this form, with a caveat: there’s a certain performance overhead involved in the algorithm that determines the name of the property behind the scenes – as you can see, that name is not passed into the GetPropertyValue and SetPropertyValue methods, so to do anything useful, XPO has to figure it out itself. Our thought was that in many cases this overhead would be offset by the productivity gain of the simple syntax.

Now we recently found a technical problem that makes this approach more problematic. The issue is in our algorithm that analyzes the call stack to find the name of the property being used – there are cases where this just doesn’t work, apparently because the .NET 2 compiler employs improved mechanisms of inlining method calls.

In case you have already implemented this approach, I’m sorry to say that we will probably not be able to fix the problem itself. We do have instructions for a workaround, so that you can be sure your implementation will not start to malfunction. There are two things you can do, alternatively:

  1. In any assembly that has persistent classes that use the syntax above (or any other related syntax where the property name is not passed in explicitely), add the following assembly level attribute: [assembly: System.Diagnostics.Debuggable(true, true)]
  2. Add the following attribute to each property getter and setter that calls one of our methods with this syntax: [MethodImpl(MethodImplOptions.NoInlining)]

In any case let me repeat, the technical issues combined with the performance problems earn this approach the label Not Recommended.

Case 2 – automatic value storage, recommended syntax

public class Person : XPObject {
  ...

  public DateTime Birthday {
    get { return GetPropertyValue<DateTime>("Birthday"); }
    set { SetPropertyValue("Birthday", value); }
  }

  ...
}

This approach is similar to case 1 above in that it uses automatic storage of the property value (the same functionality that is otherwise exposed via the GetMemberValue and SetMemberValue methods), but the name of the property is being passed in explicitely. Thereby it avoids the performance problem as well as the technical issue of case 1. This approach can be recommended, it has only one drawback: there’s no local variable for the value storage, so if you have business logic implemented in the class and you want to access the value of the field, you always have to go through our helper methods. This may of course, in turn, introduce a performance issue.

Note: While writing this article, I discovered that one of the overload of the GetPropertyValue method that is used in the sample above, does not actually exist – or rather, it has been removed accidentally. This is true for versions up to 6.3.3 – I haven’t looked in which version this overload disappeared. We are going to add the overload back in of course, until then you’ll have to use this of this format instead: return (DateTime) GetPropertyValue(“Birthday”);  In other words, the non-generic version of the method is available, the generic one isn’t.

Case 3 – local variable storage

public class Person : XPObject {
  ...

  private DateTime birthday;
  public DateTime Birthday {
    get { return birthday; }
    set { SetPropertyValue("Birthday", ref birthday, value); }
  }

  ...
}

This is now simple to explain: a local variable is being used to store the field value, and yet another overload of SetPropertyValue is called (once more including the name of the property in the parameter list) to set it. This approach doesn’t have any drawbacks, so it is recommended.

Summary

In all the cases where SetPropertyValue is being used, the syntax is relatively concise compared with the samples we published earlier in relation to the notification requirement for property setters (again, see here for the explanation of that requirement). The SetPropertyValue method, regardless of the overload you use, performs the notification for you. A variant of the approach (case 2) can use automated storage for those cases where you don’t need quick access to a local variable. We recommend you use case 2 or case 3 depending on your needs.

Once again, we don’t recommend you use the syntax described for case 1 above – it may work for you in certain circumstances or when taking good care and applying the necessary workarounds, but the performance of the approach is a problem in any case.

Free DevExpress Products - Get Your Copy Today

The following free DevExpress product offers remain available. Should you have any questions about the free offers below, please submit a ticket via the DevExpress Support Center at your convenience. We'll be happy to follow-up.
Tags
No Comments

Please login or register to post comments.