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

Add proposal for using aliases allowing type parameters and additional target types #4452

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

cston
Copy link
Member

@cston cston commented Feb 20, 2021

No description provided.

@cston cston marked this pull request as ready for review February 22, 2021 20:00
```

A partially bound type is not valid.
The `using` aliases below are both valid, and the use of `MyList<>` is valid because the expansion `List<>` is an unbound type, but the use of `MyDictionary<>` invalid because `Dictionary<string,>` is a partially bound type.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding an example of a valid use of MyDictionary. This section is still starting with the words "A partially bound type is not valid.", which doesn't really address the confusion.

static void F<T>(Option<T> t) { ... } // error: 'T' must be value type in 'Nullable<T>'
```

However, without explicit constraints, the compiler will treat `T?` as `Nullable<T>` in an alias target which means nullable reference types cannot be used with type parameters in aliases.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we even permit T? at all? Or if we do, is this line even true? If we view these as macros, then T? will mean whatever T? would mean to the final expansion, not anything predefined like Nullable<T>. For example, using MyMap<T> = Dictionary<T, T?>; would cause different expansions for int and string, where one would be mapped to int? and one would be mapped to string?.

using Option<T> = System.Nullable<T> where T : struct;
```

Explicit constraints would also allow restricting the use of the target type.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Base automatically changed from master to main March 12, 2021 19:15
@jcouv jcouv self-assigned this Sep 10, 2021
@sylveon

This comment has been minimized.

@CyrusNajmabadi
Copy link
Member

@sylveon I've hid your post for being off topic to this pr. If you would like other features added to the language, please use github-discussions to open the topic. Thanks.

@sylveon
Copy link

sylveon commented Oct 16, 2021

But I was told by @tannergooding to raise this concern here...

@tannergooding
Copy link
Member

tannergooding commented Oct 16, 2021

@CyrusNajmabadi, I think the question here was on topic. Its a question that directly relates to the feature being exposed here and if a somewhat common ask is being considered or is out of scope

If nothing else, having it being called out in the doc as out of scope covers the consideration.

@CyrusNajmabadi
Copy link
Member

I don't think proposals are the place to tack on general questions/requests for other features. That's what discussions are for.

A mechanism to export an alias is an entirely new thing and needs to be discussed and potentially championed first.

@tannergooding
Copy link
Member

tannergooding commented Oct 16, 2021

A mechanism to export an alias is an entirely new thing and needs to be discussed and potentially championed first.

I don' think the ask was to export an alias (e.g. what's covered under ## Alternatives already). It was specifically asking if the following was being considered so that Alias is only available via first using MyNamespace; or directly MyNamespace.Alias:

namepsace MyNamespace
{
    global using Alias = Name;
}

This is a specific concern around global aliases leading to increased pollution of the global namespace and thereby increasing the number of conflicts and other potential issues you can run into.


The pollution bit is a legitimate concern/consideration that directly relates to what's being proposed. The question about if scoping is or has been considered relates to the "most obvious" solution around mitigating that direct problem.

e.g. If I as a package author decide to ship some global aliases (for whatever reason) in my NuGet package (either via the MSBuild support or an implicitly included source file); what problems is that going to cause and has this been considered from the language side of things.

  • The same consideration exists for source generators
  • This comes up for cases like interop bindings where many aliases (typedefs) may exist and for other considerations as well
  • This is all still source only. You can add global usings via an ItemGroup in your csproj, and therefore via any props/targets in your NuGet package or via implicitly included source files (also a feature of NuGet)

This was already immediately visible with the new global using feature in C# 10/.NET 6 that was initially opt-out in the SDK and then had to be made opt-in because of the number of conflicts that were caused. So with the using alias feature being further extended by this proposal, the issue may become even more prevalent and is something that (at least IMO) needs to be considered as part of the overall design/proposal and if the feature would be usable or not with a minor tweak (hence the comment on the PR that adds the initial design proposal).

@tannergooding
Copy link
Member

I pinged you in the .NET Evolution Discord to continue the discussion to avoid polluting the PR further :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Language/design
Development

Successfully merging this pull request may close these issues.

6 participants