Properties with backing field.

Topics: C# Language Design
Aug 13, 2014 at 4:35 AM
Edited Aug 16, 2014 at 11:06 AM
It is a common scenario in which we need some custom code on either set or get method of the property but not both.
I have a suggestion for that which is in C# 6 way of doing things.

When you only need to change set method:
private string _userName;
public string UserName
{
    get = _userName;
    set
    {
        if (value == "James")
            throw new ArgumentException("James is not allowed.");
        _userName = value;
    }
}
or when only custom get method is needed:
private string _displayName;
public string DisplayName
{
    get { return string.Format("Welcome {0}",_displayName); }
    set = _displayName;
}
UPDATE:
I'm updating my suggestion and adding support for method delegation for get/set as following example:
private string _displayName;
public string DisplayName
{
    get += GetDisplayName;
    set += SetDisplayName;
}

private string GetDisplayName()
{
    return string.Format("Welcome {0}",_displayName);
}

private void SetDisplayName(string value)
{
    if (value == "James")
        throw new ArgumentException("James is not allowed.");
    _displayName = value;
}
Aug 13, 2014 at 8:49 AM
I think this is generally the same idea:
https://roslyn.codeplex.com/discussions/550266
Aug 13, 2014 at 10:03 AM
The idea is to make property writing easy, which is same, but the way it can be done in your suggestion is quite different.
In your suggestion the 'field' special keyword is required, which is redundant and unnecessary in my opinion.
Aug 13, 2014 at 3:35 PM
Edited Aug 13, 2014 at 3:37 PM
That is the point: the idea is the same. Only one solution (if any at all) should be officially implemented that satisfies all our needs, but that mandates careful design and planning no matter how trivial it seems. It's better to keep all those use-cases and proposals in one place to better explore the possible solutions.

About redundancy: I don't really see that much difference. You do introduce a new construct in the language with the accessor "initializer". I trade that for a keyword/local symbol. Others for implicit method/delegate calls. The actual syntax becomes even less redundant since there is no explicit field declaration. True I'm not really happy about a new keyword but that's the tradeoff for a more compact syntax and also matches the value keyword in the setter body.
Aug 13, 2014 at 4:23 PM
Edited Aug 13, 2014 at 4:23 PM
What I would like to see would be a means of specifying the name and access of the backing field associated with an auto-property. Thus:
public int X { readonly _X; get; }
or
public int X {
  protected _X; public get; // Field, and read auto-accessor
  public set { _X = value; OnXChanged(EventArgs.Empty); }
}
The latter would allow _X to be written only in the constructor, as with any other read-only variable (thus assuring anyone reading the code that it wouldn't be changed elsewhere--an assurance otherwise not presently available). The latter wouldn't offer a huge advantage over fully implementing the property manually, but would make clear the intention that the read accessor should always reflect the state of the field [if the intention was that a read accessor might in future do other things, then it should be written out explicitly even if in the first version of the code all it does is read the field].
Aug 14, 2014 at 7:59 PM
@BachratyGergely A little search on suggestion for properties results in many topics, so I decided to create a separate topic for this. There isn't a one place or at least I couldn't find it.

@supercat The backing field itself, is the main problem and your second suggestion is pretty good, but doesn't it violate the C# basic rules? There isn't variable _X type indicator or there shouldn't be any other command other than set and get. These little changes have bigger impact than it seems.
You know in my point of view we shouldn't alter the language basic rules as much as possible and keep new changes low profile, yet strong.

I have updated the suggestion and added method delegation for get/set.
Aug 15, 2014 at 4:33 PM
salar2k wrote:
@BachratyGergely A little search on suggestion for properties results in many topics, so I decided to create a separate topic for this. There isn't a one place or at least I couldn't find it.

@supercat The backing field itself, is the main problem and your second suggestion is pretty good, but doesn't it violate the C# basic rules? There isn't variable _X type indicator or there shouldn't be any other command other than set and get. These little changes have bigger impact than it seems.
You know in my point of view we shouldn't alter the language basic rules as much as possible and keep new changes low profile, yet strong.

I have updated the suggestion and added method delegation for get/set.
I think this discussion is intended to discuss what C# could be--not what it presently is; since at present the only things that are legitimate within the outer braces are get, set, and access qualifiers, and since none of those things can be identifiers, an identifier couldn't be anything other than a backing field; if one is using auto properties, there's only one possible type the backing field could have. In other proposals, I've suggested var backingFieldName as syntax, but that doesn't quite match other uses of var since the type would be inferred to match the property rather than the value of an expression. I wouldn't have any opposition to using a keyword like var or ref before the variable, but I'm not sure what keyword would be best.

I tend to think that in many cases class members should be protected rather than private, except when making them private would offer some concrete benefit. The original class author can't know everything that sub-class authors might want to do; the fact that he may not see a reason why a subclass would need to access something doesn't mean a subclass author won't. While there are many cases where making things private does offer a concrete benefit (typically by allowing the base-class author the ability to change the member's behavior in future versions of the class), it should be the class author, rather than the language designer, that makes such a determination, especially in cases where everything about the language's behavior would be specified except for the names of compiler-generated identifiers.
Aug 16, 2014 at 4:35 AM
Edited Aug 16, 2014 at 11:07 AM
@supercat you do have a point and i'm not arguing with that and how we want C# to be.
About they way you suggest backing field to be, I see two ambiguous implementation scenarios:
Will the suggestion allow developers to write this kind of code:
public int Count 
{ 
    protected _count;
    get; 
    set;
}
And if the method delegation for get/set finds its path to the specs how your suggestion will deal with it?
There are a few suggestions but here is my suggestion implementation as example:
public string DisplayName
{
    protected _displayName;
    get += GetDisplayName;
    set += SetDisplayName;
}
private string GetDisplayName()
{
    return string.Format("Welcome {0}",_displayName);
}

private void SetDisplayName(string value)
{
    if (value == "James")
        throw new ArgumentException("James is not allowed.");
    _displayName = value;
}
This doesn't seem to be clean nor easy to read.
Aug 17, 2014 at 10:02 AM
Edited Aug 22, 2014 at 8:41 AM
salar2k wrote:
public string DisplayName
{
    protected _displayName;
    get += GetDisplayName;
    set += SetDisplayName;
}
private string GetDisplayName()
{
    return string.Format("Welcome {0}",_displayName);
}

private void SetDisplayName(string value)
{
    if (value == "James")
        throw new ArgumentException("James is not allowed.");
    _displayName = value;
}
This doesn't seem to be clean nor easy to read.
There's not much point in using delegates for accessors unless the delegates are reusable. If they are tied to the backing field of a specific property you may as well write a traditional inline accessor. You might want to add a ref string field argument to the signature or something similar to distinguish properties.