Home Dashboard Directory Help
Search

Enhanced Automatic Properties by John Rusk


Status: 

Closed
 as Won't Fix Help for as Won't Fix


3
1
Sign in
to vote
Type: Suggestion
ID: 332659
Opened: 3/12/2008 12:57:38 AM
Access Restriction: Public
0
Workaround(s)
view

Description

It would be nice to be able to have more power and flexibility in automatic properties, while still retaining their concise syntax. How about something like this...

public int Foo { MyGetMethod; MySetMethod}

...where MyGetMethod and MySetMethod are user-written methods? Typically, they would be generic methods on a base class, used over and over by many different properties in derived classes.

The compiler would still generate the backing field (as at present), but the field would be accessed via the user-specified generic methods. The names of the getter and setter methods can be whatever the programmer likes.

No matter what the names of the methods, their signatures would have to look something like this:

T MyGetMethod<T>(T field);
void MySetMethod<T>(ref T field, T value);

How could this be used? Consider the example of wanting to provide property change notification, and assume the use of something like ActiveSharp (http://www.codeplex.com/ActiveSharp ). You can write something like this:

void MySetMethod<T>(ref T field, T value)
{
     field = value;
     PropertyInfo changedProperty = ActiveSharp.PropertyMap.GetProperty(this, ref field);
     OnPropertyChanged(changedProperty.Name);
}

T MyGetMethod<T>(T field)
{
    return field;
}

Put these 2 generic methods in your base class (whatever it may be) and you can have automatic properties _with_ change notification, using a nice compact syntax like this:

public int Foo { MyGetMethod; MySetMethod}

Just as compact as the present syntax; but more powerful :-)

-------

PS: The method signatures could in fact be looser than suggested above. The looser approach can be explained by this pseudo code:

TProperty MyGetMethod(TField field);             // might be generic; might not...
void MySetMethod(ref TField field, TProperty value);

where (a) TProperty must either be a generic type or else an explicit type which matches that of the property in question.

and (b) TField must be either an explict (non-generic type); the same generic type as TProperty; or a generic type based on TProperty.

So all these would be valid:

string MyGetString(string field);                 // only works for string properties
void MySetString(ref string field, string value);

T MyGetEntity<T>(EntityRef<T> field);             // compiler-generated field is EntitySet<T>
void MySetEntity<T>(ref EntityRef<T> field, T value);

T MyBoxingGet<T>(object field);                 // compiler-generated field is "object"
void MyBoxingSet<T>(ref object field, T value); // box/unbox no matter what the type

(There's no reason why the base class cannot define say several different pairs of methods, with different names, and properties from derived classes can each use the names of the methods that suit them best.)

Finally, for obscure reasons ;-) the parameter to the Getter could actually be "by ref" (perhaps _optionally_ by ref, so it is up to the programmer declaring the method to decide whether it is by ref or not.) Reason is here: http://dotnet.agilekiwi.com/blog/2008/02/enhanced-automatic-properties.html

FYI: I have previously made this suggestion in the comments here: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=278125 , but have now made it into an item in its own right.
Details
Sign in to post a comment.
Posted by Thomas Mutzl on 5/22/2008 at 8:42 AM
any chance to realize this feature with attributes?
I would love to use a syntax like:

[OnPropertyChanged]
public int foo { get; set; }

Or even:

[OnPropertyChanged("FirstName")]
[OnPropertyChanged("FullName")]
public string FirstName{ get; set; }

public string FullName
{
            get
            {
                return string.Format("{0}, {1}", LastName, FirstName);
            }
}
Posted by Microsoft on 4/24/2008 at 12:36 PM
Thank you very much for your proposal!

When we designed auto-properties we were doing it at least the third time around. The previous designs died because of the complexity they ended up exhibiting, in an attempt to capture myriads of scenarios like the one you describe. While elegant in itself, it is one of those kinds of things that, if you have enough of them, you have to ask yourself: how bad is it really to just use the existing properties - declare your private field and be done with it!

Once you have wiring up like you propose, we'll immediately have questions about why not allow the same for methods - allow one method to delegate to another without having to write a method body that explicitly calls the other one. Etc.

All in all we are quite happy that we kept auto-props simple this time, and actually shipped them. granted they do run out of steam pretty quickly, but falling back to explicit field declaration isn't a disaster.

One thing that I do regret is that they provide a temptation to make mutable properties that should really have been immutable. I would like in some future version to have get-only autoprops. We already know that this will not be in the next version (our plate is full) and there are some hard design issues about initialization.

On a specific note, if we ever were to do a feature like yours I'd prefer to explicitly keep the get and set keywords in there; otherwise the visual recognition of the property would become too weak.

Thanks again,

Mads Torgersen, C# Language PM
Sign in to post a workaround.