-
Notifications
You must be signed in to change notification settings - Fork 4k
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: Implicit Interfaces #2146
Comments
The compiler might be able to sneakily handle that within the code that it compiled itself but it couldn't affect how other assemblies might treat that type. To make the CLR recognize You might want to submit this as a feature request to the CoreCLR team. |
Is it related to intersection types? |
@dsaf, not really, but I can see the proximity to that idea. The concept behind this is closer to type verification by implementation. I remember reading about a feature that some languages have where the class is defined not by some concrete Type concept, but rather by the functionality that the class provides. By this, a class can be considered to implement an interface simply by implementing the contract it states (whereas C# requires you to explicitly state you're implementing the interface, even if the contract happens to match some other interface). This could considered be a partial implementation of that feature, but still keeping to the ideals which already exist in C#. |
@HaloFour, I was going to say that the CLR wouldn't have to change, citing that
could be converted by the compiler into
before translating to IL. However, now that I think about it further, it would still need to have a type for any variable which holds an Regarding use in other assemblies, those assemblies would have to reference this one to get the type definition of |
You could handle this via a helper method that does some reflection (obviously caching the results). I actually had some incubator project some years back to provide a duck-typing helper method that would construct a concrete proxy class in a dynamic assembly that would implement the interface members and point them to compatible members of the target type. It worked nice but it had the same issues where the proxy type isn't the same as the target type and you can't convert between them. The compiler would have the same issue. If it emitted a synthetic type the instance is no longer the original type. You couldn't pass that |
In that case it might make more sense to remove the braces: implicit interface ICombined : IComparable, IConvertible; |
I wonder if intersection types would be a better fit, since there is little reason to give a name to the combination. |
Have lots of these types in https://github.com/dotnet/coreclr/issues/2179 that require naming for ease of use. |
I would prefer that we could alias and cast or check for a group of type than making new implicit interface For solving your problem it would better if we just
Syntax is But it would require CLR support |
@Thaina, I think your idea is good. I like the idea of declaring the shorthand in the using statement. I think the |
The I wonder how much of either concept that the compiler could implement without CLRsupport. There are tricks that the compiler could do within a method, but it would have to be pretty limited. |
@HaloFour, you are correct: the desired syntax for this should be |
Intersection types would add a great deal of expressiveness to the language. I really want to see this implemented and I'm really happy to see renewed interest. This would allow for much more powerful and expressive consumption of generic APIs and allow for powerful, typesafe ad hoc cross axial classification of types. I think the As for the question of declaring a name for some intersection type, I think the |
I have seen many proposal about intersect/union type at Should we have some thread or tag to sum up all these kind of proposal as |
@Thaina the problem is that while where T: IComparable, IEquatable works very well already for specifying intersecting type constraints, it is impossible to call such a method (with resorting to dynamic) without casting to a type implementing both interfaces. Such a definition may not be available, and if it is it is still not ideal. I would welcome a thread gathering ideas for these proposals, but it is about much more than specifying generic constraints. |
Issue moved to dotnet/csharplang #344 via ZenHub |
The Problem
Define an interface in such a way that its entire purpose is to represent a set of other interfaces.Suppose you have two interfaces:
Now suppose you want to create a property on an object into which you can place an object of either type. Since they have no common ancestry, you would have three options (that I've seen, you may devise your own):
object
and then test/cast in order to access the functionalityIA
andIB
, we useIComparable
andIConvertible
?This only works for classes which specifically implement the
ICombined
interface. You would not be able to assign types likeint
,double
, andstring
, each of which implement bothIComparable
andIConvertible
.The Solution
We introduce a new usage of theimplicit
keyword for interfaces.IComparable
andIConvertible
can be interpreted as implementingICombined
.The remainder of the code could stay the same, but now, in addition to explicit implementations of
ICombined
we could also assign any type which implements bothIComparable
andIConvertible
, includingint
,double
, andstring
.Additionally, you could use this new interface to define a collection of such objects:
Defining an interface this way, it becomes retroactive. That is, types which implement all base interfaces for the implicit interface also are said to implement the implicit one.
The Rules
Finally, the run-time will have to do some type checking, which it should do already for the
is
andas
keywords. It wouldn't need to know all implicit interfaces that a type implements, it would just need to check as requested.This basically asks, "Does the type of
6
, which isint
, implementICombined
?" To determine that, it sees thatICombined
is an implicit interface so it asks, "Does it implement all of the interfaces implmented byICombined
?" So it's equivalent to writing:Simple field and property assignments would be compiler-verifiable.
The text was updated successfully, but these errors were encountered: