Another interesting issue came up today with a C# IDE feature. It involved the following piece of code:

interface IFoo<T> {
    void Bar<U>(U u) where U : T
}

class MyFoo : IFoo<int> {
}

We have a feature called "implement interface" which Anson blogged about here. We offer you the option to implement the interface implicitly or explicitly. The reason that this is interesting is that in the above code you cannot implement the interface implicitly. Why not? Because you would end up with the following code:

class MyFoo : IFoo<int> {
     public void Bar<U>(U u) where U : int
}

The problem is that the "U : int" constraint is not valid and is not something that can be expressed in the runtime. We also can't produce:

class MyFoo : IFoo<int> {
     public void Bar<U>(U u)
}

Because you're not necessarily implementing all the methods of IFoo and the runtime won't allow that either. The only way you're allowed to actually implement that specific method of the interface is to do:

class MyFoo : IFoo<int> {
     void IFoo<int>.Bar<U>(U u)
}

In that case you don't need to put on the constraints (they're known since you're explicitly stating what interface method you're implementing) and everyone is happy. Unfortunately, there's an issue with this. The user just stated "i want to implement the interface implicitly". What do you do? We came up with a few options each with what we could do:

  1. Implement the method incorrectly, i.e. with the "U : int" constraint. Won't compile and won't be very clear how to fix the problem
  2. Implement all the methods we can do implicitly implicitly, and any method we can't we do explicitly. It works but we didn't do what you asked
  3. Pop up a dialog stating "we can't implement this interface, would you like to implement explicty: 'yes', 'cancel'? It works but it adds an extra step to the process of implementing the interface
  4. Don't offer the smart tag option to implement the interface implicitly. It prevents the issue but it would be completely unclear why we didn't show it. (I would think that) most people would think some weird intellisense bug was occurring.

How do you think that this sort of situation should be handled? Each has the plusses and minuses. However, with many intellisense features we generally try to go with the model that you should be able to perform the action and go about proceding with coding extrmely quickly. Dialog boxes interrupt that flow, questions interrupt that. The flip side of that is that you want to be able to perform intellisense actions and understand exactly what will happen. The more 'error tolerance' we add, the more unclear it becomes to the user how it's going to behave. Where is the line drawn in these sort of areas?