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

Proposal: Type Alias Declaration #7451

Closed
alrz opened this issue Dec 12, 2015 · 24 comments
Closed

Proposal: Type Alias Declaration #7451

alrz opened this issue Dec 12, 2015 · 24 comments

Comments

@alrz
Copy link
Member

alrz commented Dec 12, 2015

In addition to an using-alias-directive which "introduces an identifier that serves as an alias for a namespace or type within the immediately enclosing compilation unit or namespace body", an alias-declaration can be represented as a type-declaration and be referenced by a type-name anywhere within the same assembly.

  • Aliases will be erased during compile-time and will be replaced with the underlying type.
  • Aliases can be declared wherever a type might be declared, including a block scope (Proposal: Nested local functions and type declarations #259).
  • Aliases can not have any access modifiers. Also no attributes except for source-only ones (#6671).
  • Aliases are totally equivalent to the underlying type but, for example, IntelliSense could be extended to suggest only extension methods on the specific type alias.
@alrz
Copy link
Member Author

alrz commented Dec 14, 2015

This behaviour could be added to the #3993, meaning that type aliases declared in wherever other than a compilation-unit be accessible through type-name wherever in the same assembly (via namespace, etc), as long as it wouldn't be a breaking change.

@mpeelen
Copy link

mpeelen commented Dec 14, 2015

I'm very happy to have found this proposal and would love to see it become a thing. Hurrey =)

Edit: Would it be possible to provide this feature for interfaces, too?

@alrz
Copy link
Member Author

alrz commented Dec 14, 2015

@mpeelen It should be. Also enum. I'm not sure if extending the existing using directive would be ambiguous or not, if that wasn't the case, it would be something like this using IFoo = IFoo<object>;.

@ig-sinicyn
Copy link

Small note here.

The approach with compile-time erasure will block some interesting features such as f# unit types and/or sql domain types.

If these are not planned in foreseeable future, all seems to be ok. Otherwise, at the end there will be two competing ways to declare the type alias.

@ilmax
Copy link

ilmax commented Dec 15, 2015

+1, love this one

@alrz
Copy link
Member Author

alrz commented Dec 15, 2015

@ig-sinicyn

The approach with compile-time erasure will block some interesting features such as f# unit types and/or sql domain types.

The is no concept of aliases in the CLR. So currently there is no way to expose them that way. Without CLR support, they will be solely a language feature and will be erased, just like F# type abbreviations.

at the end there will be two competing ways to declare the type alias.

You're right, this should be just an extension to the existing using-alias-directive. The problem is that with introducing new scoping for aliases, it might be a breaking change, so there should be some additional keyword to distinguish between the two. Clearly, class or struct are not good choices. Probably internal or alias itself — the latter even already exist for extern-alias-directives.

@ig-sinicyn
Copy link

@alrz

The is no concept of aliases in the CLR.

agreed. However, c# already solved this with attribute annotations. Examples: c# dynamic, extension methods, tuples (#347), c#7 non-null reference types etc.

You're right, this should be just an extension to the existing using-alias-directive

I'm not sure that reusing the using is a good idea.

Using directive is local,
the current proposal allows to define assembly-wide aliases
and (if there will be) domain types had to be reusable across multiple assemblies.

Wouldn't it be better to use distinguishable syntax for each of them?

@alrz
Copy link
Member Author

alrz commented Dec 15, 2015

@ig-sinicyn I don't know if using attributes for this would be an adoptable option. "Wouldn't it be better to use distinguishable syntax for each of them?" then we're back to your point, "at the end there will be two competing ways to declare the type alias."

@ig-sinicyn
Copy link

@alrz

Ok, let's summ it up:

  1. If there're plans to reuse type aliases across the assemblies -or- type aliases will evolve into smth alike domain types of f# unit types the approach wtih compile-time erasure will not work.
  2. There're two possible approaches: extend the using or introduce a new keyword. Both are ugly:)

@alrz
Copy link
Member Author

alrz commented Dec 15, 2015

@ig-sinicyn Just to mentioned, F# type abbreviations also use erasure. "Both are ugly" I don't know what do you mean by "ugly", it should be consistent, even if it's consistently "ugly", as you say. do you have any non-ugly syntax in mind?

@ig-sinicyn
Copy link

@alrz

F# type abbreviations also use erasure.

AFAIR they're stored as a resource, proof.

I don't know what do you mean by "ugly",

Oops, sorry:) I meant to say both of them have drawbacks, no clear winner here.

@alrz
Copy link
Member Author

alrz commented Dec 15, 2015

@ig-sinicyn Units of measure and type abbreviations are not the same thing. The proposed feature is similar to the latter rather than the former.

@ig-sinicyn
Copy link

Oops, got it. Thanks for the correction!

@orthoxerox
Copy link
Contributor

👍 I am tired of copying things like using IFoo = IDictionary<Tuple<LongIdentifierFoo, LongIdentifierBar, LongIdentifierBaz>, LongIdentifierQux>; across multiple files.

@HaloFour
Copy link

HaloFour commented Jan 4, 2016

I think I'd prefer it if the C# compiler borrowed project-wide aliases from VB.NET in the form of a command-line argument (which can be set through project properties):

/using:"Foo=System.Int32"

That wouldn't handle any of your "scoped alias" concerns, but is it really that necessary to be able to define an alias only within a block of code smaller than a single file? Judging from the comments here and elsewhere that I've seen I'd say the most common request is project-wide (if not solution-wide).

@alrz
Copy link
Member Author

alrz commented Jan 4, 2016

@HaloFour #2044 (comment)?

@HaloFour
Copy link

HaloFour commented Jan 4, 2016

@alrz

If I interpret @gafter 's comment correctly it seems to be in reference to the C# compiler having to read non-C# source files (such as JSON) in order to affect the compilation. I wouldn't suggest going that route but rather using command-line arguments to the compiler itself. The compiler already has command line arguments which affect how it treats source files, although perhaps none that affect name resolution like this would (aside /reference but that likely doesn't count.)

To note the second proposed solution to #2044 is a using global statement which is very similar to what you propose, at least for project-wide aliases.

@alrz
Copy link
Member Author

alrz commented Jan 4, 2016

@HaloFour I don't see how command-line args would solve this, because, then, the source must be compiled with a specific set of args for aliases, therefore, there will be a config-like file and we're back to gafter's comment.

@HaloFour
Copy link

HaloFour commented Jan 4, 2016

@alrz Which is the same situation for language version, references, resources, etc.

I'm not a big fan of project-wide aliases in general. Makes me think of the #define mess that results with c/C++ and I'd prefer to not have to hunt down the equivalent of header files to figure out what any given piece of code means.

@alrz
Copy link
Member Author

alrz commented Jan 5, 2016

@HaloFour I think the ability to name specific types for DDD scenarios or the use case @orthoxerox mentioned would be nice. Also with introducing named tuples it actually provides a lightweight syntax to name specific tuple types to be used across the project without declaring new ones (where it's not really necessary). Also, it's nothing like #define in C/C++ because it just aliases a type, not a bunch of code. Thoroughly, I think it would be useful regardless of syntax, but I don't think making it a "configuration" thing really fits its purpose and, as you said, the fact that it affects the name resolution. As for #2044, while it suggests a way to add global usings for namespaces (which I believe inspired by Razor), same for aliases with generics or more complicated types like tuples wouldn't work very well.

@jnm2
Copy link
Contributor

jnm2 commented Dec 21, 2016

This is different, but I wish that I could create a type alias which would allow me to change a type name or namespace or even assembly, and still have Type.GetType work against the alias. Kinda like type forwarding but with full name forwarding as well.

@alrz
Copy link
Member Author

alrz commented Dec 21, 2016

would allow me to change a type name or namespace or even assembly,

This is quite like that,

namespace Foo {
  type Str = System.String;
}

But without proper clr support to expose its metadata, it would represent the exact same type as System.String (think reflection etc).

@gulshan
Copy link

gulshan commented Mar 13, 2017

Move this proposal to csharplang repo please. I want this.

@alrz
Copy link
Member Author

alrz commented Mar 13, 2017

@gulshan Filed issue: dotnet/csharplang#259.

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

9 participants