I suggest you ...

Allow "default" values on automatic properties

When using auto-properties, I should be able to set a default value without having to create a constructor, like I can with a field:

Something like:
public bool IsActive = true { get; private set; }

1,331 votes
Vote
Sign in
Check!
(thinking…)
Reset
or sign in with
  • facebook
  • google
    Password icon
    I agree to the terms of service
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    Danny TuppenyDanny Tuppeny shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →
    completed  ·  Visual Studio TeamAdminVisual Studio Team (Product Team, Microsoft) responded  · 

    We’ve now added initializers to auto-properties, which addresses this scenario. Additionally we are allowing getter-only auto-properties.

    These additions can be tried out in the CTP of Visual Studio “14”. For links to that, and details about the new C# language features, please check out this CodePlex post:
    https://roslyn.codeplex.com/discussions/552378

    Thanks for the great feedback!

    Mads Torgersen [MSFT]
    C# Language PM

    69 comments

    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      I agree to the terms of service
      Signed in as (Sign out)
      Submitting...
      • Daniel SmithDaniel Smith commented  ·   ·  Flag as inappropriate

        I think this is fantastic. It addresses the main pain point of automatic properties, and the syntax is intuitive, clean and succinct.

        On a separate but related note, I'd love to see the addition of a notify keyword to automatic properties so we could implement INotifyPropertyChange without having to write a lot of repetitive boiler plate code:

        string Name { get; set; notify; } = "My default value";

        See the suggestion on Connect which has a bunch of positive votes:

        https://connect.microsoft.com/VisualStudio/feedback/details/348849/automatically-generate-inotifypropertychanged-implementation-for-auto-generated-properties

      • Shiv KumarShiv Kumar commented  ·   ·  Flag as inappropriate

        Mads, Please don't include this feature in a way that you've described. I feel that this simply pollutes the C# language. This can easily be done using code snippets and maybe Roslyn can be used to make smarter code snippets.

        I'd hate to be a Roslyn hater because it has made it simple for you guys to add compiler magic and make it difficult to understand C#.

      • Pavel Evgenjevich TimoshenkoPavel Evgenjevich Timoshenko commented  ·   ·  Flag as inappropriate

        Dear Mads Torger, I hope that you will hear my opinion. I'm worried if developers implement this approach, I was very disappointed that the next hack. It is also one of the possibilities to write low-quality code:
        class MyClass(int x) {
        public int X { get; } = x;
        }
        If the project contains a large number of such classes, it clearly indicates the urgent need to refactor code. I am firmly convinced that you are trying in every way to improve this language. You aim to prevent pollution of the language. Therefore, explaining your point of view you take off our apprehensions.

      • AnonymousAnonymous commented  ·   ·  Flag as inappropriate

        @Will: Thank you very much for such a nice comment. I would be very sad if Microsoft's guys will realize this syntax:

        public int X { get; set; } = x;

        It's a tautology! Trying to simplify the code, which is already very simple.
        I think that first of C# community expects agile encapsulation, bringing together all the code lines relating to the property and minimizing **** code. I'm all hands to a more appropriate syntax:

        F prop{set{...self...} get{...self...} default{self = ....}|self=... }

      • will motillwill motill commented  ·   ·  Flag as inappropriate

        what about for blocks with defined setters getters , how will this work ?????
        if it is only for auto get set then......... it is......nearly.....pointless

        the properties as they are set defaults already which no one asked for, which is un-strict
        consider the following

        public void Test(){
        Console.WriteLine(MyString); // result "" great its not null is that great ?
        Console.WriteLine(MyStringPropFull); // returns "" k great but shouldn't it be null so its set by default
        Console.WriteLine(SomeClassProp); // guess what its fine again
        }
        public static string MyString { set; get; }
        public static string mystring;
        public static string MyStringPropFull{set{mystring = value;}get { return mystring; }}
        public static SomeClass SomeClassProp { set; get; }
        public class SomeClass{ public static string mystring; }

        public int Width{get;set;} = 0; // no var but only a half step
        public string MyObjProp{set;get;} = null; // ok so now it will be null

        so in the other example Width(set;get;} = 1;
        if this is all i ever need to do with Width, i might as well just have the int width = 1;

        so as a real example usage .......

        i don't want width to be set to less then 0
        that's a given here so...
        i don't want a variable that i might forget about the accessor's
        i want control over the variable thru accessor's Only
        i want to set the default value myself

        i need the above with some sort of self keyword ....at present...
        if i try'd to force the code i ..Want..below with a little round about all
        i end up with is a stack overflow that's as close as i can get

        so this is what i want bare minimum

        public int Width
        {
        set{ Width = value;} // make it self = value; whatever i don't care
        get
        {
        if(Width < 0)
        return 0;
        else
        return Width;
        }
        }
        the above is all i want and need i don't even need the stupid } = 0;
        but it would be nice to have a default construct
        since the compiler already is using one as we have seen from the example test

        better yet is the initializer as well or rather
        F prop{set{...} get{...} default{self = ....} }

        so instead of what is needed im going to get... something silly
        public int Width(get;set;}=0;

        we NEED a self keyword in there

      • Anonymous commented  ·   ·  Flag as inappropriate

        As the feature is already implemented, as announced on this year's Build conference, it doesn't need our votes any more.

      • Anonymous commented  ·   ·  Flag as inappropriate

        @will: well, specifically for your example, why allow having negative Width at all? You must care in the setter to not allow the negative values. But if you would ever really need such a logic, come on, declare the backing field explicitly, this is still possible. The new feature is for simplifying the code in natural simple cases, not in the complicated cases (where the developer has full control already).

      • AntuanAntuan commented  ·   ·  Flag as inappropriate

        I really do not like the embodiment of the feature offered by Visual Studio team
        Admin (Mads Torgersen). Especially if it is implemented the possibility of writing bad smelling code such as

        class MyClass(x, y) {
        public property X {get; set;} = x;
        public property Y {get; set;} = y;
        }
        Do not think that follow code is not very good looking:
        new MyClass { X = x, Y = y }
        In most cases, presented above code of the class shows the poor quality of architecture. Then it may be worth a look in the direction of design patterns and perform the necessary refactoring. Of all cases to me more like an embodiment of the feature proposed by Timoshenko. In the following example, I would like to clarify the possibility of its use in inheritance:
        class BaseClass {
        public virtual string AutoAssignableDefaultProperty {
        default = "Test";
        get { return self;}
        set { self = String.IsNullOrEmpty(value) ? default (AutoAssignableDefaultProperty) : value; }
        }

        public virtual string AutoMethodDefaultProperty {
        default { return "Test"; }
        get { return self;}
        set { self = String.IsNullOrEmpty(value) ? default (AutoAssignableDefaultProperty) : value; }
        }

        public void Test()
        {
        Console.WriteLine("NVADP: {0}, {1}”,
        this.NonVirtualAssignDefaultProperty, default(this.NonVirtualAssignDefaultProperty));
        Console.WriteLine("NVMDP: {0}, {1}”,
        this.NonVirtualMethodDefaultProperty, default(this.NonVirtualMethodDefaultProperty));

        Console.WriteLine("VADP: {0}, {1}”,
        this.VirtualAssignDefaultProperty, default(this.VirtualAssignDefaultProperty));
        Console.WriteLine("VMDP: {0}, {1}”,
        this.VirtualMethodDefaultProperty, default(this.VirtualMethodDefaultProperty));
        }
        public string NonVirtualAssignDefaultProperty {default = "BC_NVADP"; get;}
        public string NonVirtualMethodDefaultProperty {default { return "BC_NVMDP"; }; get;}
        public virtual string VirtualAssignDefaultProperty {default = "BC_VADP"; get;}
        public virtual string VirtualMethodDefaultProperty {default { return "BC_VMDP"; }; get;}

        }

        class ChildClass : BaseClass {
        public new string NonVirtualAssignDefaultProperty {default = "CC_NVADP"; get;}
        public new string NonVirtualMethodDefaultProperty {default { return "CC_NVMDP"; }; get;}
        public override string VirtualAssignDefaultProperty {default = "CC_VADP"; get;}
        public override string VirtualMethodDefaultProperty {default { return "CC_VMDP"; }; get;}
        }

        ChildClass cc = new ChildClass();
        cc.Test(); ((BaseClass) cc).Test();

        In order to understand the results, let's see how AutoAssignableDefaultProperty and AutoMethodDefaultProperty properties are disclosed:
        AutoAssignableDefaultProperty:
        private string _autoAssignableDefaultProperty = default_AutoAssignableDefaultProperty();
        public string default_AutoAssignableDefaultProperty() { // NOT VIRTUAL!!! May be inline
        return "Test";
        }
        public virtual string get_AutoAssignableDefaultProperty()
        {
        return _autoAssignableDefaultProperty;
        }
        public virtual void set_AutoAssignableDefaultProperty(string value)
        {
        _autoAssignableDefaultProperty = String.IsNullOrEmpty(value) ? default_AutoAssignableDefaultProperty(): value
        }

        AutoMethodDefaultProperty:
        private string _autoMethodDefaultProperty = default_AutoMethodDefaultProperty();

        public string virtual default_AutoMethodDefaultProperty() { // VIRTUAL!!!
        return "Test";
        }
        public virtual string get_AutoMethodDefaultProperty()
        {
        return _autoMethodDefaultProperty;
        }
        public virtual void set_AutoMethodDefaultProperty(string value)
        {
        _autoMethodDefaultProperty = String.IsNullOrEmpty(value) ? default_AutoMethodDefaultProperty(): value
        }

      • Anonymous commented  ·   ·  Flag as inappropriate

        this is captain kirk ... scotty i need full power ... i don't care what you call it ...
        call it a super duper pooperty ... just get it running in the next 3 minutes
        or were all dead the klingons (c++) will blow us up :)~

        public int Len
        {
        default{Len = 0; }
        public get { return Len; }
        private set{if (value < 0) { value = 0; } Len = value;}
        }

      • Anonymous commented  ·   ·  Flag as inappropriate


        // whats purposed well its ok
        public int Len{get;set;} = 0;

        // dunno how this will work
        int len = 0;
        public int Len
        {
        get { return len; }
        private set
        {
        if (value < 0) { value = 0; }
        len = value;
        }
        } = 10; // ?? i dunno

        // what i want cause its like star wars emperor sidious i can yell "unlimited power !!!"
        // no more variable
        public int Len
        {
        default{Len = 0; }
        public get { return Len; }
        private set
        {
        if (value < 0) { value = 0; }
        Len = value;
        }
        }

        your bud willy motilly

      • Justin MinnaarJustin Minnaar commented  ·   ·  Flag as inappropriate

        --

        So on a related note, I think that the PropertyChanging and PropertyChanged events should be automatically implemented by the compiler as follows.

        This would prevent issues with renaming a property and forgetting to change the string containing the name and would also remove the need to setup FODY or something similiar.

        public class Example
        {
        // unusual but possible, also the auto function could then be used
        // in numerous other places, like on functions... more on this next time.
        public int X { get; set; } auto PropertyChanging
        public int Y { get; set; } auto PropertyChanged
        }

        public class Example
        {
        public int X { get; set; } auto PropertyChanging, PropertyChanged
        public int Y { get; set; } // not on this one
        }

        public class Example auto PropertyChanging, PropertyChanged
        {
        public int X { get; set; }
        public int Y { get; set; }
        }

        After all, these functions are so standard that perhaps they should be provided as a standard in the language, as was done with foreach and with linq

        And is there anything wrong with the following?

        public class Example auto PropertyChanging, PropertyChanged
        {
        public int X { get; set; }, Y { get; set }
        }

        or perhaps

        public class Example auto PropertyChanging, PropertyChanged
        {
        public int X, Y { get; set; }, Z { get; }
        }

        I assume that there is absolutely no need to write a property with only a set; unless we want to raise the OnPropertyChanged or similiar event?

        And I would expect the compiler to automatically insert the necessary functionality for the PropertyChanging, PropertyChanged functions.
        Then any standard function could be written as follows and work in different places

        public static class ExampleExtensions
        {
        public event EventHandler NowHappy;

        public static void Happy.get(this object sender, int x, int y) { return "" + x + ", " + y; }
        public static void Happy.set(this object sender, int x, int y, int value) { .... x = ... y = ... raise NowHappy(sender, a, b); }
        }

        public static class Example auto Happy
        {
        public property AB auto Happy
        {
        int a, b;
        get { return "" + a + ", " + b };
        set { ... some code here ... }
        }
        }

        public static class ProblemSolver
        {
        public property XY auto Happy
        {
        int x, y;
        get { return "" + x + ", " + y };
        set { ... some code here ... }
        }
        }

        The above would then result in adding the NowHappy event to both classes, and result in raising the event on both property's set actions.

        Just had to share a few thoughts. Hopefully something in the above is worth thinking about.

      • Justin MinnaarJustin Minnaar commented  ·   ·  Flag as inappropriate

        Just sharing my thoughts. Thanks to the team for the fantasic C# language and development environment!

        --

        Given that the default syntax creates a variable behind the scenes, could it be named?

        If so, the following autogenerated property

        public int Y { get; set; } = 1;

        translates as...

        // Using the keyword self from the suggestion made by Pavel
        public int Y
        {
        int self = 1;
        get { return self; }
        set { self = value; }
        }

        --

        This would make it possible to override the get or set operation without writing the other, as in...

        public class Example
        {
        public int X
        {
        get { return Math.Min(100, self); }
        set;
        }

        public int Y
        {
        get;
        set
        {
        if (self == value) return;
        value = Math.Min(100, self);
        self = value;
        OnPropertyChanged("Y");
        }
        } = 1;
        }

        --

        Personally I find the private variable initization at the end of the block rather confusing and
        think it could be difficult to read. From a point of scope, and a point of declaration before usage,
        I would prefer to have the init { } operation at the beginning of the property scope, whatever we
        name it as. I vote for the 'self' variable as suggested by Pavel.

        To support more complex initialization, perhaps we could write the following properties?

        public class Example
        {
        // This creates the public get and public set functions...
        public int X { self = 1; get; set; }

        // This only creates a public get function without the set function, meaning that
        // and initialises the value using a function and the value never changes thereafter.
        public int Y { self = calculateY(); get; }

        // This creates a property where I write a complex init function
        public int Z
        {
        self
        {
        var a = someotherclass.something();
        var b = yetanotherclass.somethingelse();
        return Math.Max(a, b);
        }
        get;
        }
        }

        I went with the idea of returning a value from the 'self' function to be consistent with the 'get' function.
        Alternatively, this could be a void method that assigns the self value, similiar with the 'set' function.

        From the above it then suggests the property block contains three items, the 'self', 'get' and 'set'.

        --

        Since the 'self' item can be written as

        self = value;

        or as
        self { return value; }

        does this not also suggest that the 'get' and 'set' could be written either way, for example

        public class Example
        {
        public int P
        {
        self = 0;
        get = self * 2;
        set = value / 2;
        }
        }

        or

        public class Example
        {
        public int P
        {
        self { return 0; }
        get { return self * 2; }
        set { self = value / 2; }
        }
        }

        Perhaps we should only support the functions and not the assignment inside the block?

        --

        This also begs the question, why can't I place multiple local variables inside the scope of the property block?

        This would allow things like...

        public string MyProperty
        {
        static int lastValue = 5;

        int a = 0;
        int b = 0;

        internal string prefix = "";

        public get { return prefix + " " + a + ", " + b; }
        public set { parseABfromString(value, out a, out b); }
        }

        The above is not the cleanest example, but just to make a point.

      • gzakgzak commented  ·   ·  Flag as inappropriate

        @mads,

        I had a feeling this implies primary constructors, and I'm glad to hear that the two are coming together (wasn't sure what the name was earlier).

        How would primary constructors work in the case of multiple constructors? I'm curious to see the design thinking around this case.

      • Terry FosterTerry Foster commented  ·   ·  Flag as inappropriate

        Still surprised and peeved that this wasn't originally implemented with auto-properties, but glad it's finally being considered. I actually avoid auto-properties a lot of the time because I don't want to have to create a constructor where I set the initial value which is then displaced from my property declaration. I prefer to just create the backing field next to my property. With this simple feature addition, I will be using auto-properties much more.

      • Anonymous commented  ·   ·  Flag as inappropriate

        Totally onboard with this, it is a great way to cleanup code. However, I think that I'm on the same page with a lot of people when I say that we need a way to create our own auto-property definitions. What I mean is that we need a way to encapsulate basic logic that we are using all over the place so that our code remains DRY

        I.E. - Create a hybrid of an extension method available to a property:
        //Setter has three arguments (new value, backing field, and containing class) and returns void
        public void CantBeNull<TProperty, TClass>(this TProperty value, TProperty backingField, TClass containingClass) where TProperty : class where TClass : IMyInterface
        {
        if (value != null) backingField = value;
        }

        //Setter has three arguments (new value, backing field, and containing class) and returns void
        public void MustBePositive<TProperty, TClass>(this int value, TProperty backingField, TClass containingClass) where TProperty : int
        {
        if (value != null && value >= 0) backingField = value;
        }

        //Getter has two arguments (backing field and containing class) and returns the property type
        public TProperty ReturnDefaultIfNull<TProperty, TClass>(TProperty backingField, TClass containingClass) where TProperty : class, new()
        {
        return backingField ?? new T();
        }

        Then in usage:

        public int X { get; MustBePositive set; } = x;
        public String Y { get; CantBeNull set; } = y;
        public Object Z { ReturnDefaultIfNull get; CantBeNull set; } = z;

        The idea being that you can use a well defined getter or setter independently of one another. You would provide the method implementation with type constraints in order to allow users to interact with the class from the auto property implementation. In the MVVM world with ReactiveUI this would allow you to cleanup a million entries of this:

        public class MyViewModel : ReactiveObject
        {
        private Boolean _showSomething;
        private String _statusText;

        public Boolean ShowSomething
        {
        get { return _showSomething; }
        set { this.RaiseAndSetIfChanged(ref _showSomething, value); }
        }

        public Boolean StatusText
        {
        get { return _statusText; }
        set { this.RaiseAndSetIfChanged(ref _statusText, value); }
        }
        }

        with this:

        public TProperty ReactiveSet<TProperty, TClass>(this TProperty value, TProperty backingField, TClass containingClass) where TProperty : class where TClass : IReactiveObject
        {
        containingClass.RaiseAndSetIfChanged(ref backingField, value);
        }

        public class MyViewModel : ReactiveObject
        {
        public Boolean ShowSomething { get; ReactiveSet set; }
        public Boolean StatusText { get; ReactiveSet set; }
        }

        This would be majorly awesome to see in C# - It can get really annoying really quickly when you have a large enterprise-level application that has thousands of backing fields simply to support one liner pieces of validation and such...the above code can replace a 6 line property with 1 line and a defining method

      ← Previous 1 3 4

      Feedback and Knowledge Base