Too many options!!


So i’ve noticed in quite a few of my blogs that people have complained about the #region’s we include when you’re using Implement-Interface.  Probably the most frustrating thing is that if you take the following steps:



  1. Implement some interface on a class of yours
  2. add a new method to that interface
  3. implement the interface a second time to get the new method stubbed out.

You’ll end up with code that looks like:


class C : IFoo
{
#region IFoo Members
public void Foo()
{
throw new NotImplementedException();
}
#endregion

#region IFoo Members
public void Bar()
{
throw new NotImplementedException();
}
#endregion
}


This is a pretty unpleasant experience as you know have to go in and manually clean up the regions that we’ve f****ed up.  This is especially bad when implementing some interface with a large interface hierarchy.  So what’s the right thing to do here?  Well, we should correctly re-use regions when adding new stubs from the same interfaces.  However, due to our current implementation this is actually pretty tough to do.  In the past we used to generate each stub manually and we could place it anywhere in the file.  However, this was a very unpleasant experience.  You’d get a lot of flashing as you saw the stubs being spit into the editor.  In order to improve that we generated the code for all the stubs and then just spit it in one go at the end of the file.  This makes the experience quite nice: just click “implement interface” and a moment later it’s all done.  So what can we do if the “right thing” isn’t available?  Well, we could just provide an option to not spit out the #region’s.  And, as this is actually something that has been requested by some people since they don’t like #region’s in general, it seems like a perfectly reasonable thing to do.


Now, internally, we already have a way to control this behavior using our built in schema for defining options.  All of our other options go through this same mechanism, so it was pretty trivial to hook it up to UI like we’ve done with many others.  The end result is this:


            


(you can see the new option exposed in the UI in the red box)


Will we go ahead with this in Whidbey?  I have no idea.  Will we go ahead with this post-Whidbey?  I have no idea.  I’m generally opposed to providing options unless they are absolutely necessary.  Rather, I’d like to just do the right thing and not need an option at all, if that’s possible.


Also, we’re a phase of development called “visual freeze”.  During this time we try not to change the UI at all (unless completely necessary).  Why?  Well, first of all the localization costs are huge.  VS is localized into many languages and any change you make has a 10x cost because each language team needs to do all the work to make it available for their native language speakers.  Second of all, there’s a UE cost to this as well.  We need to document this new feature and explain how it works.  That documentation then has to be localized again.  And, of course, if any of the documentation refers to this image then it will need to be recaptured in every place appropriate.  Basically, the cost is huge and it is strongly discouraged if not necessary.


Finally, we are trying to shut down.  We don’t want to make changes that could destabalize things, and we also don’t need to overload QA even more since they’re working like mad with us to raise the quality of the product super high so we can ship.  Even a little change like this which seems incredibly simple to make could potentially cause problems, and that added cost means less time spent on the rest of the stuff we want to ship.


So, given all the costs i wouldn’t want to go ahead with this change solely to help out this scenario.  However, if we could combine a whole lot of changes in one, it might make the average cost a lot lower.  i.e. if we wanted to add 5 new options then it woudl be better to get it all done at once rather than to do each one individually. 


So are there other little intellisense options that you’d like to have some control over?  i.e. things like: disabling all smart tags, turning off brace matching, etc.


In general are there options to control current features taht you feel are missing? 


Comments (22)

  1. symonc says:

    Having the ability to disable auto-formatting* just for typed code would be very useful. I tend to custom format code blocks as I type, especially method calls with long parameter lists, and having these blocks re-formatted every time a closing brace is inserted is a pain. In an ideal world it’d be great to have auto-formatting turn itself off whenever the formatting of an auto-formatted construct is manually changed, but I suspect that’s asking for too much…

    *I know you can turn off "Automatically format completed constructs and pasted source", but this disables all auto-formatting including for pasted source, which I’d like to keep switched on.

  2. I don’t use regions at all, so whenever the editor inserts them it pisses me off greatly.

    Maybe a smart way to do this would be to scan the source file and see if it uses any regions, and only create new ones when generating code if at least one is already present.

    P.S. Numerous studies have shown that white text on dark background is harder to read than black text on a light background. I found your page a bit hard to read, esp. the code sample. Why not change the look so that it respects the browser preferences?

    Dejan

  3. AndrewSeven says:

    Isn’t there a golden rule about doing nothing being better than doing the wrong thing.

    It is definitely not right to put the same named region twice.

    If regions don’t make the code easier to see and read they should not be used.

  4. James Hancock says:

    I really really want the option that was promised to me by the dev team that so far hasn’t made it into any build other than Beta 1. That is an option to set the word wrapping.

    Right now it word wraps to the left edge on all lines. I want it to word wrap to two indents more than the line that started it. i.e:

    blah blah blah blah blah blah blah blah

    blah blah

    is how it is now.

    I want it to be:

    blah blah blah blah blah blah balh blah

    Blah blah blah

    That way I can have developers not insert abristrary line breaks and have it wrap nicely and intelligently. Two tabs indent is important so that it is separated from the next line of real code. (unlike Vs.net 2003 that when you split a line between two online indents one tab.)

    This needs to be made an option. Please put it in with your region thing 🙂 It’s a pain in the ass with split lines for read ability when one person is at 1284X1024 and the other is at 1920X1280. And the way word wrap is now is completely useless and anoying.

    Thanks!

  5. I’m not a big fan of having my interface implementations in regions – at least not all of them – so I would prefer to #region-ize my code myself.

  6. Pierre Arnaud says:

    There are never enough options for the developer 😉

    I’d love an option which would allow me to align the instance variables and the properties at a given column. The current implementation of Whidbey just removes all the extra space/tabs I painfully add when editing so that my names are aligned vertically. If it could see that I am trying to align, say, property names, vertically and not touch the spaced, that would be great. But this has probably nothing to do with the code you modified for the #region stuff.

  7. Thomas Eyde says:

    You are not saying that the brand new flagship of yours has a bad architecture, do you?

    Joke aside, the right thing for you is not always the right thing for me. I hate regions, too. Collapsable code is nice, but a region hints that this code belong somewhere else or make the class too big.

  8. CyrusN says:

    James: Please send that feedback to the VS Core team. They own word wrapping, not the C# IDE team 🙁

    There are many blogs available, or you can use: http://msdn.microsoft.com/ProductFeedback

  9. CyrusN says:

    Eric: Darn it. Now that you want this i’m going to have to reject it on principle.

  10. CyrusN says:

    Pierre: "I’d love an option which would allow me to align the instance variables and the properties at a given column. The current implementation of Whidbey just removes all the extra space/tabs I painfully add when editing so that my names are aligned vertically. If it could see that I am trying to align, say, property names, vertically and not touch the spaced, that would be great. But this has probably nothing to do with the code you modified for the #region stuff. "

    I’m sending that feedback to the guys in charge of formatting pierre!

    Also, a great way to get these suggestion recognized is to submit them to http://msdn.microsoft.com/ProductFeedback

  11. CyrusN says:

    Thomas: "You are not saying that the brand new flagship of yours has a bad architecture, do you? "

    Sure i am. Well… sorta.

    More like the comprimises we made to make one scenerio work great ended up affecting our ability to agilely respond to a new demand.

    Unfortunate, but it happens.

  12. DavidMKean says:

    I would like an option to change the brace matching back to the way it was in 2003, where it simply bolds, rather than places a square box around the braces.

  13. (Wow, this got long. never ask me about things that bug me with intellisense, or any other feature I use daily. My list always seems to be long…)

    I’d love an option for when you auto-stub out a property (either by "Implement Interface" or "type the override keyword and hit tab" it would put everything on one line.

    I use the following indentation patterns for properties (depending on what fits). The smaller ones are the most common, and it’s much easier to go from a smaller one to a bigger one than vice versa. VS.NET insists on giving me the biggest, always.

    public int Foo {get {return foo;} set {foo = value;}}

    public int Foo

    {

    get {return somethingSlightlyLonger();}

    set {somethingLonger(value);}

    }

    public int Foo

    {

    get

    {

    if (cond)

    {

    return foo;

    }

    return bar;

    }

    }

    This gets even more annoying when I do "implement interface" and get lots of properties all with the wrong indentation.

    Oh, and (at least in VS2003) "implement interface" doesn’t understand overloading. Try getting VS.NET to implement this interface to see what I mean:

    public interface ITest

    {

    void DoSomething(string val);

    void DoSomething(int val);

    }

    It would also be great if "implement interface" would respect the order that the members are declared in the interface, rather than forcing them to alphabetical. Often there’s a reason for the order that was chosen…

  14. (My indentation appears to have been lost in that last comment, but hopefully it’s obvious what I meant. Naturally I don’t put everything in the first column 🙂 )

  15. CyrusN says:

    Stuart: "I’d love an option for when you auto-stub out a property (either by "Implement Interface" or "type the override keyword and hit tab" it would put everything on one line. "

    Simple: Just edit the .snippet file and you can make it spit out code exactly like that! 🙂

  16. CyrusN says:

    Stuart: "It would also be great if "implement interface" would respect the order that the members are declared in the interface, rather than forcing them to alphabetical. Often there’s a reason for the order that was chosen…"

    I’ll look into that today. Often times we choose data structures internally that have certain benefits but some disadvantages. I don’t have the code in front of me, but i’m guessing that i used a hashtable there for quick lookup by name and that’s causing the ordering to be lost.

    I’ll see if there’s something i can do about this.

  17. CyrusN says:

    David: "I would like an option to change the brace matching back to the way it was in 2003, where it simply bolds, rather than places a square box around the braces. "

    We’re discussing this. At this point it seems unlikely. However, if you file a bug a http://msdn.microsoft.com/ProductFeedback and it gets enough votes then we would probably add that option.

  18. Cyrus, thanks for the tip about the snippet trick and for looking into the member order issue.

    However, would the snippet file trick actually work for properties created using "implement interface"?

    Also, did you notice the third issue I mentioned, with method overloading in "implement interface"? (I wouldn’t normally follow up an issue like this so soon, but you’ve been so conscientious about responding to every single point raised by anyone that I suspect you missed that one in my long post…)

    Given an interface as follows:

    public interface ITest

    {

    public void DoSomething(int val);

    public void DoSomething(string val);

    }

    "implement interface" produces something like the following, at least in VS2003:

    #region ITest members

    public void DoSomething(int val)

    {

    }

    void ITest.DoSomething(string val)

    {

    }

    #endregion

    It seems that VS is checking before adding each item to see whether a member with the same name already exists, and if it does it’s adding it as an explicit-interface-implementation style method. However, it’s ignoring the fact that two members with the same name actually *can* exist simultaneously as long as their parameter lists are different.

  19. CyrusN says:

    Stuart:

    "However, would the snippet file trick actually work for properties created using "implement interface"? "

    Yup! Both snippets are configurable!

    "Also, did you notice the third issue I mentioned, with method overloading in "implement interface"? (I wouldn’t normally follow up an issue like this so soon, but you’ve been so conscientious about responding to every single point raised by anyone that I suspect you missed that one in my long post…) "

    Nope! I missed it! If i don’t respond fully after like 20 minutes, then definitely ping me. (Give me 20 because i maybe be splitting a long post into several replies)

    "It seems that VS is checking before adding each item to see whether a member with the same name already exists, and if it does it’s adding it as an explicit-interface-implementation style method. However, it’s ignoring the fact that two members with the same name actually *can* exist simultaneously as long as their parameter lists are different. "

    This is not the case on VS2005. We only move to Explicit implementation if there is actually a conflict. IF there is no conflict (like in the example that you’ve shown), then we’ll be smart and keep them both implicit.

  20. Thanks, once again, for the timely and helpful responses 🙂

    If the snippet for "implement interface" is configurable, could you avoid the option of "insert #regions around generated code" by just having people who want this behavior modify the snippet to not include the #regions?

  21. CyrusN says:

    Stuart: "If the snippet for "implement interface" is configurable, could you avoid the option of "insert #regions around generated code" by just having people who want this behavior modify the snippet to not include the #regions? "

    Good point. unfortunatley the #region is not part of the snippet. The snippet only covers teh method taht is pumped in.

    So if we put the regions in taht then we’d end up surround every method with #region’s!

    Ack!

    In the future it would make perfect sense to expand the snippet architecture so that this would fit naturally into it.

  22. Gah, the snippet architecture doesn’t have a looping construct? 🙁