eWorld.UI - Matt Hawley

Ramblings of Matt

Creating Classes in VS.NET

April 12, 2004 22:59 by matthaw

I'm sitting here at work building an application using TDD (which by itself is another post, and may be coming later), and every time I start a new class for another piece of the puzzle, I'm hating on how I have put the keyword "sealed" class in my declaration. Now, this isn't a major issue, but it can be if you plan on releasing an API for customers to build against. What's my issue? Well, I'm wondering if the "sealed" and "notinheritable" keywords should be applied by default in Whidbey.

My proposition comes from the fact that it is good design practice to have your classes become "sealed" or "not inheritable", that way your users cannot accidently inherit and break changes with your API. In practice this is a big deal, and how often are you building an API, and you become lazy to allow the default attributes/keywords/accessors be applied to a API (classes specifically, making them public instead of private or internal/friend)? I'm almost betting very frequently.

I propose that in Whidbey, and future versions, that "sealed" or "not inheritable" be applied by default to all new class declarations created by the IDE. This way, you have to make an effort and think about what you're doing when removing this keyword, and hopefully make you think if you really need to do so. 

As of right now, I realize that this can be accomplished by editing the templates used somwhere deep within the directory structure of VS.NET, so please don't tell me I can do this now. What are you're thoughts, feelings, objections to this?



Categories: .NET | General
Actions: E-mail | Permalink | Comments (10) | Comment RSSRSS comment feed

Comments

April 12. 2004 23:10

I'd far prefer an option in VS to modify my default code template - so I could specify things like my default imports, accessibility options etc...

Scott Galloway

April 12. 2004 23:13

Thats actually a far better idea, have an actual "template editor" available in the IDE. Heck they're giving us a ton of control with the keystrokes, layout, etc...why not this too Smile

Matt Hawley

April 13. 2004 04:26

There was a big discussion about this on one of the MSFT blogs a while ago; don't remember who.  People fiercely arguing both sides, as they tend to do.  I'm in the sealed camp.  People should only be able to extend classes that were designed with that in mind.  I really doubt that anyone designs every one of their classes to be used by a subclass, so the default of non-sealed doesn't make sense to me.  On a big project you wind up seeing the brittle base class probem, not necessarily because people are lazy, but because it's so easy.



+1 for sealed.

Jeff Key

April 14. 2004 08:24

As long as you don't have any virtual or protected members that why do you care if your types are subclassed?  What harm can they do?

Brad Abrams [MSFT]

April 16. 2004 17:10

My response is here:



www.cincomsmalltalk.com/.../blogView">www.cincomsmalltalk.com/.../blogView



to be blunt, this is such a bad idea I have trouble believing that anyone thought of it....

James Robertson

April 16. 2004 21:28

Eric Lippert had a few posts on sealed a while back, that's probably what you're thinking of.

Gordon Weakliem

April 17. 2004 07:37

Hey, why not just remove inheritence altogether?

http://

April 17. 2004 17:48

I think in large part your concerns are mitigated by the fact that virtual members must be opted in to, versus being default.



To accidentally "inherit and break changes with your API" presumably is more specifically a concern that, through polymorphism and the ability to override default behavior, other parts of your API reliant upon said extended classes might break?



For instance,



public class ImportantClass {

  public ImportantClass(StrategyClass sc) {

    this.sc = sc;

  }

  private StrategyClass sc;

  Int32 ComputeSomething() {

    return sc.GetState() + 10;

  }

}



public class StrategyClass {

  Random rand = new Random();

  virtual Int32 GetState() {

    return rand.Next();

  }

}



Now I "break" ImportantClass's relationship on StrategyClass by providing the following implementation, and supplying it to the ImportantClass constructor:



public class MyStrategyClass : StrategyClass {

  override Int32 GetState() {

    throw new Exception("Ha ha, you are broken!");

  }

}



In this case, yes a sealed class would have worked, but better API design would have better prevented such a problem (namely, not creating GetState() as virtual!).



In summary, the typical concern is not with interface extension, but rather simply the concern that one could substitute a new implementation that goes against the grain of its dependant's expectations.

http://

April 20. 2004 05:06

goode

Porcelain Insulator

June 29. 2004 20:30

Very Good! I like!

webrank

Comments are closed

Copyright © 2000 - 2024 , Excentrics World