Saturday, February 23, 2008

Summary of C# vNext Ideas in this Blog

Here's a summary of the ideas I've suggested in this blog, for future versions of C#:

Enhanced Automatic Properties

Recently there's been a lot of blog posts discussing things people would like to see in the next version of C#. Here's my addition to the wish-list:

"Automatic properties that let me supply a method body." It sounds like a contradiction in terms - but it doesn't have to be. Instead, it would be a compact syntax for defining properties that use standardised method bodies (where you define your own "standard" bodies).

Some places where it would be useful:
  1. Cases where many properties follow a standard format.  For instance, all the properties generated by the LINQ designer could be single-line automatic properties.  (Much less verbose than the current approach).
  2. ORM's and similar products that require properties to be written according to certain conventions.  (E.g. Mindscape LightSpeed)
How would it look?

Right now, we can write automatic properties like this:
public int Foo { get; set; }
My suggestion is that the words "get" and "set" could be replaced by the names of methods. For instance:
public int AdvancedFoo { GetValue; SetValue; }


Where the methods "GetValue" and "SetValue" are generic instance methods with these signatures:
/// <summary>
/// When passed the field, return the property value
/// </summary>
T GetValue<T>(ref T field)
{
// ... your own code goes here...
}

/// <summary>
/// When passed the field, by ref, and the new property value, set the field
// </summary>
void SetValue<T>(ref T field, T value)
{
//...your own code goes here...
}
Given the above property, "AdvancedFoo", the compiler would compile it as if I had written this:
public int AdvancedFoo
{
get { return GetValue(ref _advancedFoo); }
set { SetValue( ref _advancedFoo, value); }
}

private int _advancedFoo; // compiler-generated backing field
Just as in today's automatic properties, the compiler would generate the backing field for me. The difference is that it reads and writes that backing field via methods which I define.

This goes a long way towards giving the best of both worlds: the compact syntax of automatic properties, and the flexibility of my own code (plus standardisation - all me properties that are supposed to work the same way do work the same way, because they all use the same code).

Questions:

Why does the "GetValue" method take the field "by ref"? SetValue needs it by ref, but why GetValue? GetValue takes it by ref simply so that you can use this trick to find out which property is being read - just in case you need to know. This is something you are more likely to need to know when setting, e.g. to raise change notificiations, but maybe some people want to identify the property in GetValue too. Using the ref param makes that possible.

What type should the complier use for the backing field? Simply put, it should use whatever field type is implied by the field parameters of the "GetValue" and "SetValue" methods. E.g. an automatic property for a LINQ EntityRef might look like this:
T GetEntity(ref EntityRef<T> field) where T:class
{}

void SetEntity(ref EntityRef<T> field, T value) where T:class
{}
allowing me to write this:
public Customer Bar{ GetEntity; SetEntity; }
and have the compiler compile it as if I had written this:
public Customer Bar
{
get { return GetEntity(ref _bar);}
set { SetEntity(ref _bar, value);}
}
private EntitySet<Customer> _bar;

Note that the compiler is able to infer that the backing field should be EntitySet, not Customer, based on the signatures of Get/SetEntity.

(And how would Get/SetEntity actually work? That's a question for another day ;-) I do have some (working) prototype code...)

What do you think of this idea for enhanced automatic properties?

Update 2 March: posted on MS Connect here (in the comments)

Update 12 March: And here here as an MS Connect item in its own right.

Thursday, February 14, 2008

Extension Methods - Feedback to Microsoft

If you've been following the disussions about extension methods in this blog, you might be interested to know that I've submitted the issue to Microsoft's feedback site. Jump over there and vote for it, if you'd like to see something done.

Friday, February 08, 2008

Better Property Change Notification

aka Automatic INotifyPropertyChanged

Some time ago I developed a new way to do property change notification. It consists of code which can automatically figure out which property has changed, without you having to tell it.

Details are here.

I've now put together an updated version, and posted it on CodePlex here.

Here's how to use the new version:

Option 1:

Here's the easiest option...

Add this code to your class or base class:
PropertyChangeHelper _propertyChangeHelper = new PropertyChangeHelper();

public event PropertyChangedEventHandler PropertyChanged
{
add { _propertyChangeHelper.Add(value); }
remove { _propertyChangeHelper.Remove(value); }
}

protected void SetValue<T>(ref T field, T value)
{
_propertyChangeHelper.SetValue
(this, ref field, value);
}
Then write your property setter methods like this:
public int Foo
{
get { return _foo; }
set { SetValue(ref _foo, value); }
}

Option 2:

If you want more control, you can find which property changed like this (and then do whatever you like):
protected void SetValue<T>(ref T field, T value)
{
...
field = value;   //Actually assign the new value
PropertyInfo changedProperty = PropertyMap.GetProperty(this, ref field);
// do whatever you like, now that you know which prop was changed
...
}
Key differences in the new version are:
  • No "trial sets". The old version used to call all your property setters, to figure out which fields they corresponded to. That could be annoying, because you ended up recieving calls to the set methods when your objects were not necessarily ready for them. The new version doesn't need to do this. Instead, it inspects the MSIL of the set methods, to figure out what it needs to know. (The inspection is a one-off runtime operation, so it won't be a performance problem.)
  • Fewer contraints on how classes are coded. The old version required that you nominated a special field as the "reference field", to which all others were compared. The new version does not require that. Also, the new version lets you use your own base class (with your own SetValue method, named whatever you want). Fianlly, you can put your own code in the property setter methods (along with the call to your "SetValue" method), something which could cause problems in the old version
  • Helper class for easy implemetation of property change notifications (as above)
  • Granualar implementation, so that you can call some of the implmentaiton classes, but still write the outer "layer" of the API yourself if you need to
  • Lock-free. The new version is threadsafe without explict locks (and without and [ThreadStatic]s). Update 10 Feb: This used to rely on a little trick with generics and static fields; but that doesn't play well with inheriance. It now uses a class I wrote called LazyDictionary, which is basically a dictionary with double-checked locking to ensure that locks are only requested during initialization, and not during the on-going running of the application. (Didn't want a lock request on every property set call!)
  • No separate C++ assembly. The old version used managed C++ to do stuff that C# cannot. The new version uses reflection emit, to produce the corresponding routine on the fly, so that the separate assembly is not required.


Finally, I have resurrected the name "ActiveSharp" (which I used for a previous, abandonned project) for this new version of the code. I did that for two reasons, firstly the new version borrows code from the old ActiveSharp (particulaly the MSIL inspection); and secondly I liked the old name and couldn't think of a better one ;-) Just like the previous "ActiveSharp", this new version is a product of my microISV, Tasman Logic Ltd. (The microISV is not exactly a money-making venture, given that its only product is open-source ;-)