Proposal: Associated types #3046
Replies: 4 comments
-
The syntax is probably a non-starter, But really, aside from reducing the number of The 2nd benifit you mention at the end is kinda vague, how does the compiler offer improved help? And lastly, we can't we just use nested types for this which already exist? |
Beta Was this translation helpful? Give feedback.
-
I don't get the point of I'm not sure I get the point of the rest. You can already accomplish that with namespaces or nested types. |
Beta Was this translation helpful? Give feedback.
-
I don't like the name, since associated types are already a completely different thing. Extension nested types? I also don't feel the benefit/effort ratio is high enough. This is a change that affects a lot of places in the compiler while not providing a lot of benefit. |
Beta Was this translation helpful? Give feedback.
-
Look very closely to In fact if we allow shape to be generic and able to extend static member we could have something like this public shape Generic<T> extend T
{
public static List<T> List => new List<T>;
}
var intList = int.List; And |
Beta Was this translation helpful? Give feedback.
-
Disclaimer: This proposal is not related to a language feature with same name "Associated types (for protocols/traits)" in Swift or Rust. Csharplang already has a proposal regarding that concept in #1328 "Existential types". This proposal can go with some other name, if deemed more appropriate to convey the idea. Suggestions are welcome.
Also this proposal is a syntactic sugar and does not enable anything new in the language C#, which is not already possible. This feature may improve ergonomics of C#.
The basic idea:
The basic idea of this feature is allowing a
.
in type names, where the "first part" of the name separated by the.
has to be name of another type. Then the current type with a.
in its name will be called an "Associated type", denoting its association with the former type, which is being called the "subject type". This can bring some naming conventions syntactically available to the compiler and tools. For example, with this feature, it would be allowed to use types/classes named asCustomer.Repository
,Customer.Controller
,Customer.Service
,Customer.ViewModel
instead of these currently used
Customer
-related classes-CustomerRepository
,CustomerController
,CustomerService
,CustomerViewModel
These
.
-ted names of these classes clearly denotes that, all these types are associated with the "subject" typeCustomer
.Then there can some buildups over the basic idea. As per the rule, the first part of an associated type has to be another type. So it prevents spelling and naming errors to some degree. Also it will facilitate syntactically aware refactoring of code. Also compiler can generate an warning/error if the subject type (the type being associated with) is not used in the definition of the associated type.
Then there can even be chained associated types. For example, there can be an associated type
T1.AT2
for typeT1
. And then another associated typeT1.AT2.AT3
, which will be regarded as a type associated with the previous typeT1.AT2
. This proposal however does not propose any other changes for these types, like access to members or something else. And we can go even further from this basic idea.Generic associated types:
Generic associated types are types associated with a "generic type parameter" instead of a "concrete type". This means there can be types such as
int.List
orByte.Buffer
instead ofList<int>
orBuffer<Byte>
. Using this, there can be some nice looking type signatures of the generic types we use. For example, there can be-class T.List<T>
(when instantiating, no need to supplyT
in angle brackets, just useT.List
)class K.Map<K, V>
(supplyK
as subject type andV
in angle bracket to instantiate asK.Map<V>
)class (T1,T2).Action<T1, T2>
(instantiate as(T1,T2).Action
)class (T1, T2).Func<T1, T2, T3>
(instantiate as(T1,T2).Func<T3>
)etc.
These new associated classes can be used along with the current type signatures like
class Dictionary<T1, T2>
. Some probable generic associated types can be-T.List
T.Task
T.OrNull
(Option type)T.OrException
(Result type)K.Map<K, V>
T.DbSet
And with generic associated types comes another possibility- "association chaining" for generic associated types. Which enables types like-
int.List.Task
instead ofTask<List<int>>
string.Map<Customer>.Task
instead ofTask<Map<string, Customer>>
(int, string).Func<Customer.Task>
instead ofFunc<int, string, Task<Customer>>
In my opinion, this feature enables the similar kind of chaining available to types which was enabled by extension methods for methods. With extension methods, devs can design to call a method like
a().b().c()
instead ofc(b(a()))
. I think this chaining can alleviate some mental pressure from developers when understanding the meaning of a type, just like what extension method chaining did for function calls. Just to be clear, the decision of which types becomes a generic associated type is fully in the hand of designer developers of that particular type, not arbitrarily in the hand of the consumer developers.As Associated type names are similar to inner classes, it will be illegal to have an inner class and an associated type having same (qualified) name.
Listing the probable benefits again at the conclusion-
Beta Was this translation helpful? Give feedback.
All reactions