BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News C# Futures: Primary Constructors

C# Futures: Primary Constructors

This item in japanese

Bookmarks

We last mentioned primary constructors in 2014 when it was removed from the candidate list for C# 6 and VB 12. Late last year, Primary Constructors reappeared as proposal #2691, which is now a candidate for C# 9.

The basic idea behind a primary constructor is it reduces the amount of boilerplate code needed to initialize a class.

 

class C(string x)
{
    public string X
    {
        get => x;
        set { 
            if (value == null) 
                throw new NullArgumentException(nameof(X)); 
            x = value; 
        }
    }
}

compiles as…

class C
{
    private string _x;
    
    public C(string x)
    {
        _x = x;
    }
    public string X
    {
        get => x;
        set { 
            if (value == null) 
                throw new NullArgumentException(nameof(X)); 
            x = value; 
        }
    }
}

Richard Gibson summarizes how they would be useful:

A quick sample taken from our codebase of 30 classes shows that 22 of them (73%) had an explicit constructor defined and of those 21 (> 95%) did nothing other than set private readonly fields) are dumb, tedious, can be auto generated, are rarely read--normally skipped over--by humans (because they're usually so dumb) and are therefore a surprisingly common source of bugs.

He goes on to explain those bugs usually come down to accidentally assigning a constructor parameter to the wrong field.

This concept heavily overlaps with the records proposal we reported on in Easier Immutable Objects in C# and VB. MgSam writes,

This proposal seems completely incompatible with the current record proposal. And I disagree with the statement in the proposal saying this is more widely useful than records. I think this saves a little bit of boilerplate- records (and related features of auto-generating GetHashCode, Equals, ToString) can potentially save a ton of boilerplate in a lot of scenarios.

HaloFour also weighed in on the topic:

With the way records have been proposed for C# they include symmetric construction and deconstruction as well as identify based on a specific set of properties. Primary constructors get you all of that in one parameter list given that the parameters are also properties and that list gives you an order in which those properties can be deconstructed.

C# records, as they have been proposed, are more like Scala case classes or F#'s single case unions, and both languages define the construct by how they are constructed.

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • Confusing.

    by Andrew Witte,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    This seems like the wrong way to go about this as its generating hidden methods.
    Why not just have constructors with no bodies?

    // current way
    class C
    {
    private float _x, _y, _z;

    public C(float x, float y, float z)
    {
    _x = x;
    _y = y;
    _z = z;
    }

    public X
    {
    get => _x;
    set {_x = value;}
    }
    }

    // short hand way
    class C
    {
    private float _x, _y, _z;

    public C(x:_x, :_y, :_z);// optional parameter name override on left of ':' char

    public X
    {
    get => _x;
    set {_x = value;}
    }
    }

  • x or _x

    by James Curran,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    In the "compiles as" code above, the private member is "_x", while the X property references "x". Does that work?

  • Re: x or _x

    by Jonathan Allen,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    They're still debating that. Some want x, some _x, and some a mangled name with matching property.

  • Re: Confusing.

    by Jonathan Allen,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    That makes more sense to me.

  • Awful. Just awful.

    by Andrew Stephens,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I once knew a programmer who always used variable names of no more a couple of characters in length, to reduce the amount of typing he had to do. It feels like the same thing is happening with some of these C# syntax changes - sacrifice readability for the sake of saving a line or two of code. I appreciate that I don't *have* to adopt these new approaches, but features like this are terrible imho.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT