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

Support for CSharp 9 #207

Open
danielmarbach opened this issue Sep 7, 2020 · 8 comments
Open

Support for CSharp 9 #207

danielmarbach opened this issue Sep 7, 2020 · 8 comments
Labels
enhancement New feature or request

Comments

@danielmarbach
Copy link
Member

  • Record types
  • Init accessor (?)
@danielmarbach danielmarbach added the enhancement New feature or request label Sep 7, 2020
@stakx
Copy link
Collaborator

stakx commented Jan 6, 2021

I'll add another to the list:

  • Map System.IntPtr and System.UIntPtr to the new type keywords nint and nuint (?)

This is debatable. System.IntPtr has traditionally been used to represent an unmanaged pointer in interop scenarios. nint doesn't transport those semantics quite as well, it looks more like any regular integer type. I am not sure what we should do about these keywords.

Init accessor

This would be reasonably straightforward as the setter's return type gets annotated with a System.Runtime.CompilerServices.IsExternalInit modreq.

This would be a prerequisite for...

Record types

Sensible support for record is currently very difficult for several reasons:

I think we should start by focusing on init-only setters.

@Shane32
Copy link
Contributor

Shane32 commented May 18, 2022

As of 5/17/2022, Visual Studio 17.2.1 and/or SDK 6.0.300 uses the CompilerGenerated attribute for more methods of record types which changes the output of PublicApiGenerator. See:

In my application, these methods of struct record types are not listed anymore in the output:

  • Deconstruct
  • Equals (both typed and object overload)
  • GetHashCode
  • ToString
  • operator !=
  • operator ==

Additionally, for class record types, these methods are not listed in the output:

  • PrintMembers
  • protected constructor for cloning
  • public clone method (named <Clone>$)

@sungam3r
Copy link
Member

Also see #247

@stakx
Copy link
Collaborator

stakx commented Dec 30, 2022

As with IntPtr vs. nint (see above), I am also wondering whether record types should actually be rendered using the record keyword or simply as the class-es that they really are (see also the discussion at dotnet/csharplang#4121 (comment)). Any opinions on this?

@sungam3r
Copy link
Member

I think that no one wants to see all that internal default stuff for records : <Clone>$, PrintMembers, etc. I would like to see only overridden methods and record keyword instead of class.

@sungam3r
Copy link
Member

Actually all that stuff is filtered out now by CompilerGenerated attribute. OK. Another argument - what if one has switched from record to class or vice versa? It can be a breaking change for consumers that override some method so I would like to see when it happens.

@sungam3r
Copy link
Member

sungam3r commented Dec 30, 2022

  // in core library
        public record User(string login, string password); // switch to User1

        public class User1 : System.IEquatable<User1>
        {
            public User1(string login, string password) { }

            public string login { get; init; }

            public string password { get; init; }
        }

        // in some external library
        public record Admin(string login, string password) : User(login, password)
        {
            protected override bool PrintMembers(StringBuilder builder) // BOOM after swithing from record to class for User
            {
                builder.Append("BlaBlaBla");
                return base.PrintMembers(builder);
            }
        }

User and User1 APIs are equal.

@sungam3r
Copy link
Member

Well, I found a bug. See PublicApiGeneratorTests.Record. This test has wrong expectedOutput if we treat User as class (for now we do). It should contain public bool Equals(User other) but this method is filtered out by CompilerGenerated attribute. The fix for that situation - switch class keyword to record!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants