0
public interface IInterface { }

public class MyClass { }

public static class Program {
    public static void Main() {
        IInterface myVariable = new MyClass();
    }
}

I would expect this code to work since MyClass does satisfy IInterface, but I get a compilation error:

error CS0266: Cannot implicitly convert type `MyClass' to `IInterface'. An explicit conversion exists (are you missing a cast?)

Why?

Is there a workaround I can use that doesn't involve an explicit conversion?

Servy
  • 202,030
  • 26
  • 332
  • 449
Kinrany
  • 99
  • 1
  • 9
  • 3
    Is your code example incomplete? It doesn't look like MyClass implements IInterface to me... – Jesse Carter Jun 30 '17 at 20:25
  • 3
    you mean, interface implementation in MyClass ? like `public class MyClass : IInterface{ }` – Akash KC Jun 30 '17 at 20:26
  • 4
    C# doesn't support duck typing. –  Jun 30 '17 at 20:26
  • can you post the code how you implemented the interface? – Ravi Shankar Jun 30 '17 at 20:26
  • 1
    Why do you expect `MyClass` to be an `IInterface`? They have nothing to do with one another (according to your code) – maccettura Jun 30 '17 at 20:26
  • 4
    "MyClass does implement IInterface" no it doesn't. – vcsjones Jun 30 '17 at 20:27
  • A similar code would work if instead of assigning to `myVariable` I used the new object in a function call. What's the difference? – Kinrany Jun 30 '17 at 20:35
  • Please show the similar code that does work in your question. – Scott Chamberlain Jun 30 '17 at 20:40
  • @Kinrany What's the difference between calling a method on an object and assigning it to a variable of a type it isn't convertible to? Well, one is a method call, and one is an assignment that needs to ensure that the assigned value is a valid value of the variable it is being assigned to. What about them is the same? – Servy Jun 30 '17 at 20:41
  • 1
    You probably want to do something like: `public class MyClass : IInterface` if you want to instantiate a MyClass object as an IInterface type. – Ingenioushax Jun 30 '17 at 20:41
  • Uh, I was wrong, it doesn't. – Kinrany Jun 30 '17 at 20:42
  • C# does support 'duck typing' with dynamic. This is structural typing which is not supported. – Lee Jun 30 '17 at 20:48
  • For your edit, as servy mentioned in the top answer, [what you can call `await` on](https://blogs.msdn.microsoft.com/pfxteam/2011/01/13/await-anything/) and [what you can do a `foreach` with](https://stackoverflow.com/questions/6368967/duck-typing-in-the-c-sharp-compiler) could be considered duck typeing because both of those language features do not require a specific interface to be implemented, they just require specific methods to exist on the type. – Scott Chamberlain Jun 30 '17 at 20:49

1 Answers1

5

Unfortunately, C# or .NET does not support duck typing in this particular context.

For a type to implement a particular interface, it will have to explicitly declare that it implements this interface. You say "satisfy" now, but this has no meaning for C# or .NET.

Does the type MyClass implement IInterface? No, sadly it doesn't.

This declaration:

public class MyClass { }

Declares a class that inherits System.Object, and does not implement any interface.

The fact that the interface contains no methods or properties does not in any way make it match up with this type. The class still does not implement this interface.

The only way for a class to implement an interface is to make it explicit:

public class MyClass : IInterface { }

So no, there is no way to force C# or .NET to consider that class as one implementing this interface.

The common ways to handle this is to make a wrapper class (ie. a class that implements IInterface and contains a MyClass, delegating all methods and/or properties to the contained MyClass instance), or, you know, actually implement the interface.

To conclude, the only way to make this code compile:

IInterface myVariable = new MyClass();

is to make MyClass explicitly either implement the interface:

class MyClass : IInterface { }

or to inherit from another class that implements it:

class BaseClass : IInterface { }
class MyClass : BaseClass { }
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • You're right, MyClass doesn't implement IInterface, I'll fix that part of the question. – Kinrany Jun 30 '17 at 20:38
  • 2
    @LasseV.Karlsen That's one example, and it is indeed more of a "sort of", better examples are what you can `await` or `foreach`, or the query expression syntax. – Servy Jun 30 '17 at 20:43
  • @Servy, I edited the question to reflect this. Could you please provide a more complete answer as a full, uh, Answer instead of a comment? – Kinrany Jun 30 '17 at 20:49
  • @Kinrany It's not appropriate to edit your question to ask a completely different question than what you originally asked. But you have your answer to it anyway, as is seen in my comment, so you shouldn't need to ask a new question. – Servy Jun 30 '17 at 20:51
  • @Servy: My original answer was based on me being confused about C# and duck typing. Me, or anyone with the same wrong assumption, wouldn't be able to ask a more appropriate question, so it's probably a good idea to explain the source of the mistake instead. – Kinrany Jun 30 '17 at 20:56
  • @Kinrany And it has been explained to you. It was explained to you *even before you asked the follow up question*. The point remains that the question needs to remain the question that you originally asked. You can improve how you ask that question, but you can't change it to ask a completely different question. If the answer to your question raises more follow up questions for you, then you can ask those follow up questions in new questions (although here the answers were provided to you before you even asked those follow up questions, so shouldn't be necessary). – Servy Jun 30 '17 at 20:59