Best behavior when you can't perform an action the user specified.
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:
- 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
- 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
- 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
- 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?
Comments
- Anonymous
June 02, 2004
Most likely, I would intend to do option 2) if I knew that not every method can be implemented implicitly. I would want to see both options in the intellisense, but perhaps the implicit option would have some sort of disclaimer attached (or its wording changed) so that it's clear there's a problem with full implicit implementation. - Anonymous
June 02, 2004
The comment has been removed - Anonymous
June 02, 2004
The comment has been removed - Anonymous
June 02, 2004
Not directly relevant but.. I have recently been so annoyed by a program that continously tried to guess what I mean instead of saying "something is wrong" that I decided never to use it again. - Anonymous
June 02, 2004
Cyrus,
I think that either option 3 or 4 would be the best approach. With option 3, it only comes up in that specific situation, which is fine, and I would be appreciative that I was informed of the issue. I think that this alludes to your previous post on refactoring, where refactoring should always do the right thing. Asking the user if they want to do something else because the current course of action is not possible is the right thing.
If you go with option #4, then I would recommend a tool tip popping up over the menu item when hovering over it which indicates why it is disable. Actually, this might be good for most menu items that are disabled. It would definitely go a long way to help people understand their environment. - Anonymous
June 02, 2004
The comment has been removed - Anonymous
June 02, 2004
The cases yo have exposed are SO rare.... I would'nt care if intellisense works fine 99% of the times I use it and wrong only 1%!!! I think the case is so rare that every option is valid..
If you want to ask me what to do in a dialog and interrupt the flow of intelisense, do it. As long as you do that ONLY on the extreme cases you expose.
If you want to produce code that won't compile, it's OK!! because it's ONLY 1% of the times, i can live with that.
...etc - Anonymous
June 02, 2004
Option 2, definitely. I want the product to do what I mean (generate stubs for the interface), even if I didn't ask for it quite right.
Putting up a dialog to ask me is VERY WRONG, but a non-modal toolwindow kind of thing explaining what has been done and listing some things I might want to do instead is EXCELLENT. The guiding principle here is "don't interrupt me when I'm working", and it has the virtue of being discoverable. - Anonymous
June 03, 2004
I would go with Option 3 or Option 4, the latter, improved, as Nicholas Paldino said (show a tooltip instead of the SmartTag explaining the problem). Option 3 would be OK too.
Sorin Dolha [MCAD, MCSD .NET] - Anonymous
June 03, 2004
The comment has been removed - Anonymous
June 03, 2004
David: Take a look at anson's page http://weblogs.asp.net/ansonh
We already offer you the option to do it implicitly or explicitly. The issue is when you choose the implicit option and we can't, under any circumstances, do it implicitly.
I'm thinking an alternative is to offer two choices in the smart tag:
a) Implement interface
b) Implement interface explicitly
The first does what it can, make most methods implicit, the second does every method explicitly. - Anonymous
June 03, 2004
Radu: What program was that? - Anonymous
June 03, 2004
Nicholas: I agree. Unfortunately, our menus lack the ability to be disabled and to show a tool tip.
We could, however, completely disable the item and say:
a) Implement interface implicitly (unavailable, interface cannot be implemented implictly)
b) Implement interface explicitly
THen the interaction model is the same. There's no extra step, and we'll produce the correct code for you. - Anonymous
June 03, 2004
The comment has been removed - Anonymous
June 03, 2004
Implement it like #1, but commented out with an explanation of why it is commented out. That way - no annoying dialogs, a clear explanation of the problem - and the ability for the developer to uncomment and deal with the problem - Anonymous
June 03, 2004
I like your last idea. The reason is that I would hate for the implicit option to be grayed out just because one method of many cannot be implicitly implemented.
Then in those rare cases, the IDE won't save me much time as it could have.
I prefer having the IDE output the fact that several methods couldn't have been implemented implicitely. - Anonymous
June 03, 2004
Option 2. Implementing that function explicitly is the only way to implement the interface. Someone has to do it. It should be the Intellisense. Otherwise, you're just going to force the user to do some extra typing. - Anonymous
June 03, 2004
Use option 3, except say "Cannot implement implicitly due to method X" so the user sees what the problem is. - Anonymous
June 03, 2004
Ugh: Why can't your feedback be consistent so that it's obvious what choice to make :-)
I should just say (a la Ford) "you can have any behavior as long as it's the one we choose" ;-) - Anonymous
June 03, 2004
The comment has been removed - Anonymous
June 03, 2004
Nicole: Excellent points.
WRT dialogs. I'm not adamantly opposed ot them. I do, however, worry about going down the path where every issue becomes something that we ask the user about (Even if we provide a checkbox saying remember this choice). I'm concerned that in that sort of a model every time an issue comes up it's far too easy to resolve as 'oh lets just ask the user'. In many cases we think it's quite important to ask, but in others we feel taht we don't need to 'spam' you and can provide a quite intelligent choice otherwise.
Note: if after long discussion we decide that that isn't the case, but an option would solve this then we will use the option. See the previous thread on passing type params around by reference.
However, we don't take user interaction decisions lightly. We know that they can and will affect how people work and we want to make the choice that tries to have the most positive impact and least negative impact. Talking to you guys is a way to tell how good/bad these chocies will be. - Anonymous
June 03, 2004
"Radu: What program was that?"
Poseidon for UML CE. - Anonymous
June 03, 2004
The comment has been removed - Anonymous
June 20, 2004
Nicole: Thanks for the response. I jsut found this now (outlook had categorized it as spam).
I would like some clarification of what you mean by "Unfortunately, for each of the possible paths, I can think of at least one example where implementing with that path would end up being a worse approach than just slogging through the typing"
Could you give examples of each?