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: Default Generic Type Parameter #6248

Closed
alrz opened this issue Oct 22, 2015 · 13 comments
Closed

Proposal: Default Generic Type Parameter #6248

alrz opened this issue Oct 22, 2015 · 13 comments

Comments

@alrz
Copy link
Member

alrz commented Oct 22, 2015

The ability to specify a default type for a generic type parameter:

class Foo<TBar = Bar, TBaz = Baz> {}

As a real world example, the IdentityDbContext class in ASP.NET Identity:

class IdentityDbContext<TUser = IdentityUser, TRole = IdentityRole, TKey = string, TUserLogin = IdentityUserLogin, TUserRole = IdentityUserRole , TUserClaim = IdentityUserClaim> where ...

to avoid the need to declare different subtypes for different default types like

class IdentityDbContext : IdentityDbContext<IdentityUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim> { ... }
class IdentityDbContext<TUser> : IdentityDbContext<TUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim> where TUser : IdentityUser { ... }

In companion with improved type aliases can avoid this for god's sake.

To use default type parameters, one may skip the type parameter as follow:

var foo = new Foo<,>(); // new Foo<Bar, Baz>()
var foo = new Foo<A,>(); // new Foo <A, Baz>()

This has some interactions with generic type argument inference proposals like #5429 or #2319.

@gafter
Copy link
Member

gafter commented Oct 22, 2015

@alrz Lucky for us you're not aware of the work to add higher kinded types

oops 🙊

@alrz
Copy link
Member Author

alrz commented Oct 22, 2015

@gafter you mean like #2212? what about it, how is that relevant? :speak_evil:

@orthoxerox
Copy link
Contributor

@alrz how will you disambiguate between creating instances of classes Foo and Foo<T = Bar> via new Foo()?

@alrz
Copy link
Member Author

alrz commented Oct 23, 2015

@orthoxerox new Foo() and new Foo<>. see the examples.

@aluanhaddad
Copy link

@alrz I don't think this adds very much value.

@gafter

Luckily for us you're not aware of the work to add higher kinded types

You don't say? 😀

@alrz
Copy link
Member Author

alrz commented Oct 26, 2015

I don't think this adds very much value.

That's it? Well that was not helpful either.

@BeeWarloc
Copy link

Foo<> already have a meaning inside typeof(), which obviously can't change.
Having Foo<> mean different things inside and outside of typeof() could be a bit confusing.

@MgSam
Copy link

MgSam commented Oct 28, 2015

@gafter Any further details forthcoming on this work?

I do think this is a useful idea. It would allow users to use generic methods/types without necessarily having to specify each type if they're happy with the default, thus potentially making consumption far more straightforward.

TypeScript has a similar proposal currently.

@gafter
Copy link
Member

gafter commented Oct 28, 2015

@MgSam Any further details on what work? Higher-kinded types? If anything it is years away, and would be led by changes to F# and CLR.

@alrz
Copy link
Member Author

alrz commented Jan 23, 2016

I think this can eliminate the need for generic/non generic variations of types without breaking existing code,

interface IEnumerator<T = object> {
  T Current { get; }
  bool MoveNext();
  ...
}
interface IEnumerable<T = object> : IEnumerable {
  IEnumerator<T> GetEnumerator();
}

@aluanhaddad
Copy link

I think this can eliminate the need for generic/non generic variations of types without breaking existing code

I'm not sure what that means. Are you saying that there would be type equivalence between

interface IEnumerator<T = object> {
    T Current;
    bool MoveNext();
}

and

interface IEnumerator {
    object Current;
    bool MoveNext();
}

?
If so that would be a breaking change because

new ArrayList() is IEnumerable == true

and

new ArrayList() is IEnumerable<object> == false

and

typeof(IEnumerator<>) != typeof(IEnumerator)

@alrz
Copy link
Member Author

alrz commented Jan 24, 2016

@aluanhaddad I'm saying that we could get rid of non-generic IEnumerable.

@alrz
Copy link
Member Author

alrz commented Mar 21, 2017

Moved to dotnet/csharplang#278

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