I suggest you ...

Support implicit interfaces for code reuse

Allow us to cast a type to an interface which it implements (but does not declare or even know about). The interface can be marked as 'implicit' to ensure recipients understand that the implementation may not know about it.

The lack of implicit interfaces (and the corresponding lack of header files) in C# and VB.NET is THE PRIMARY ROADBLOCK to good architecture and testing in .NET.

I cannot see a good defense for the lack of this feature. It does not add clutter or complexity, enables drastically simpler unit tests, and (for the first time), enables interoperable code without forcing the use of an additional assembly dependency just for shared interfaces.

40 votes
Sign in
Password icon
Signed in as (Sign out)
You have left! (?) (thinking…)
nathanael.jones shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

Thanks for taking the time to share this suggestion. This item has been around for a couple of versions of Visual Studio and we haven’t acted on it. Looking at the VS “15” plans, we’re not going to take action on this item, so we’re going to close it. If the suggestion is still relevant, please either take a look to see if there’s another suggestion that’s similar that you can vote on, or open a new suggestion.
- The Visual Studio Team


Sign in
Password icon
Signed in as (Sign out)
  • Qwertie commented  ·   ·  Flag as inappropriate

    I suppose you are talking about the feature that would allow IList<T> to be cast to IReadOnlyList<T>?

    There's a feature like this in VB and a few years ago I wrote a little library to try doing the same thing in C#: http://www.codeproject.com/Articles/87991/Dynamic-interfaces-in-any-NET-language - the article starts with a benchmark so you can see the time cost of this feature (the space cost is 4 words per wrapper generated).

    AFAICT, it is not possible to avoid a "proxying layer" (wrappers) due to the way .NET is designed. And because the wrappers are separate objects, the wrappers will be visible at runtime (obj1 == obj2 is false if obj1 is a List<T> and obj2 is an IReadOnlyList<T> that points to that same list, and also obj1.Equals(obj2) will be false). Because of this, the feature probably will not be added as an implicit cast in C#, but it could and should be added as a feature of the BCL (base class library).

  • birbilis commented  ·   ·  Flag as inappropriate

    ...when I say support in the compiler, I mean to avoid the proxying layer (of course security should also be considered carefully when implementing such a thing, in case there are pitfalls)

  • birbilis commented  ·   ·  Flag as inappropriate

    It would be nice indeed if one could define at the client object's side a static interface that is a subset of the methods of a server (or serving if you prefer) object (it is only the view of the server that the client has gained knowledge of) that has been passed on to the client

    Then there could be a service (a facility I mean) that accepts the server object instance and the interface the client has defined (the duck type) and case the server object to that interface by CHECKING that the duck interface is indeed a subset of the methods the server object implements

    the check if our duck interface is indeed covered by what the object to be duck-typed offers can be implemented via reflection already

    the implementation could be hacked by spitting out a new object (bytecode generation) that wraps each property/method of the object to be duck-typed and calls into the original object, but it would be much better if there was support in the compiler for that (viewing an object via an interface that is compatible to it in functionality, not in strong typing concept)

  • nathanael.jones commented  ·   ·  Flag as inappropriate

    Verifying that a given Type matches a given Interface is both (a) pretty fast and (b) cacheable. This would, of course, have to happen at runtime.

    Declaring everything 'dynamic' is NOT a solution that's gonna fly.

    The status quo requires every library have a separate bridge library for every other library it needs to work with. Everything on NuGet has a .Castle version, a .Windsor version, etc, and nobody is willing to settle on a common logging library. We need implicit interfaces if .NET is going to move forward.

  • Philippe commented  ·   ·  Flag as inappropriate

    The problem with that idea is mainly that it is either a compile-time things (like C++ templates) in which case the same limitation would probably apply without major changes to the runtime.

    I think that dynamic keyword could often be used instead so it is not that useful.

    Also it might be hard to implement efficiently... so in the end, explicit interfaces might often be more appropriate as the compiler knows how many interfaces need to be implemented for a given type.

    There is also the case where a class is defined in a given assembly and the implicit interface is defined in another assembly. In such case, the compiler cannot do the association while compiling the first assembly as it would be the case with explicit interfaces. Thus mapping would require some run-time code to prepare a proxy but then should generated the proxy particulary in the implicit interface for a class is then used in a third assembly that is neither the one that defined the class nor the implicit interface.

  • Tim Jones commented  ·   ·  Flag as inappropriate

    Nice idea (C# meets duck typing?). I think a change of that significance probably warrants a new (or rather, new use of an existing) language keyword. Perhaps:

    implicit interface IGreet { void Greet();}

    I don't *think* that would cause an ambiguity in the grammar.

  • nathanael.jones commented  ·   ·  Flag as inappropriate

    A code example of how this would work:

    class A { public void Greet(){ /* Say hi */ }}

    interface IGreet { void Greet();}

    class B{ public void Introduce(IGreet greetable){ greetable.Greet();} }

    new B().Introduce((IGreet)new A()); //Works; Type A meets the criteria for IGreet and can therefore be cast to that type.

    new B().Introduce(new A()); //Ideally this works as well

Feedback and Knowledge Base