Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameter properties #11909

Closed
zpul opened this issue Jun 10, 2016 · 9 comments
Closed

Parameter properties #11909

zpul opened this issue Jun 10, 2016 · 9 comments

Comments

@zpul
Copy link

zpul commented Jun 10, 2016

Any chance to have parameter properties in C# 7 as in Typescript?

Reference:
https://www.typescriptlang.org/docs/handbook/classes.html#parameter-properties

@zpul
Copy link
Author

zpul commented Jun 10, 2016

This example usage of Typescript better makes the point:
https://www.stevefenton.co.uk/2013/04/stop-manually-assigning-typescript-constructor-parameters/

In C# the same example

public class Person {
    public string firstName { get; set; }
    private string lastName { get; set; } = "n.a.";

    public Person (string firstName, string lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

shortens to this:

public class Person {  
    public Person (public string firstName, private string lastName = "n.a.") { }
}

@HaloFour
Copy link

That sort of shorthand is proposed for record types: #10154

public class Person(string firstName, string lastName = "n/a");

The one thing that I don't think has currently been resolved in that proposed spec is allowing for explicit member access modifiers on the parameters of the primary constructor.

@zpul
Copy link
Author

zpul commented Jun 10, 2016

@HaloFour thanks for the pointer!

In my understanding record types are very useful but only when creating storage-only classes.

The parameter properties described above are more general I think:

  • they apply to classes in general and target any access modifier (public/private/etc.)
  • AFAIK they help/shorten a very frequent coding pattern

I would like having both, however if I have to choose one of them, I would prefer definitely parameter properties for their large applicability.

@MgSam
Copy link

MgSam commented Jun 10, 2016

I never much cared for TypeScript's implementation of this feature because it makes it harder to see at a glance what the properties of your class are.

I think that problem would be compounded even further in C#, because in C# you can have multiple constructors (in TypeScript/JavaScript, you can only have a single constructor). It would be weird to have properties declared in one constructor that might be somewhere else in the code from the constructor you're looking currently.

@HaloFour
Copy link

@zpul

Perhaps. Records can contain class bodies complete with other methods, properties, etc. But they are proposed to automatically generate other record-specific boilerplate such as a deconstructor and possibly "withers". The syntax and functionality of your proposal is very similar so maybe the two could be considered side-by-side, whereas "property parameters" can be declared in normal constructors, but are promoted to "primary constructors" when the parameter list is moved to the type declaration:

public class Person {
    public Person(public string firstName, private string lastName = "n/a") { }
}

public class PersonRecord(public string firstName, private string lastName = "n/a");

Something that your proposal might have to take into consideration is that the C# naming guidelines stipulate that property names are PascalCase while parameter names are camelCase. The record proposal solves this through having a second identifier declared on the primary parameter, e.g.:

public class Person(string firstName FirstName, string lastName LastName);
...
var person = new Person(firstName: "John", lastName: "Smith");
Console.WriteLine($"Hello Mr. {person.LastName}!");

@MgSam

You're right, as with primary constructors it could only work if the type only had a single constructor. I also agree that it would be too easy to lose track of those members, and it's weird for something declared within the parameter list of a member to have a scope beyond that member.

@zpul
Copy link
Author

zpul commented Jun 10, 2016

@MgSam Very interesting point, however I think that it can be addressed in some way.
I agree with @HaloFour that it has to be limited in some way, either this should work on classes with one constructor or it should work only on one of them.
To address your comment the languange syntax can state that this constructor should be the first one and should appear at the very beginning of the class.

@HaloFour Thanks for the valuable feedback.
About CamelCasing I am usually not very strict on it however any idea such the one on record types is fine for me.

@alrz
Copy link
Member

alrz commented Jun 13, 2016

Not as the primary syntax for records, but I think this would be useful as an alternative.

Related: #10154 (comment)

@aluanhaddad
Copy link

aluanhaddad commented Jul 1, 2016

Whenever I use TypeScript and need to create a class I use this notation for brevity but it's actually a little weird.
public and protected make sense but private is really an odd ball because it exposes an implementation detail as part of a type's interface to simplify its implementation. The counter argument is that you should follow the principle of least privilege which which suggests the use of private. However, in that case it would be better to not declare the fact that the value is being captured into a property at all, and just do the wiring manually.

@gafter
Copy link
Member

gafter commented Aug 10, 2017

Issue moved to dotnet/csharplang #804 via ZenHub

@gafter gafter closed this as completed Aug 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants