views:

121

answers:

5

There's one specific feature that I wish was in the .NET framework, but isn't. I wish there were a DBDataReader.GetString (or GetDateTime, GetInt32, etc.) overload that accepted the field name instead of the index. Using the field name makes for easier maintenance IMO, but the GetXxx methods only accept the field position.

I can add these to my project (at least in a limited capacity to suit my immediate needs) by using extension methods, but something about that feels wrong. Beyond the obvious problem that I'd have to repeat this process for every new project, is there any reason not to do what I'm thinking about?

For example, am I headed down a slippery slope of trying to rewrite the framework to suit my whims? Will I leave the poor guy who has to modify my code (probably me) scratching his head trying to figure out what's going on? Am I violating some core principle of OOP?

Just looking for guidance and viewpoints. Thanks.

+2  A: 

Actually, I think .NET did it rather nicely: For extension methods to work, you have to be using the namespace they were defined in. Visual Studio will show you where the method came from etc.

By all means, if you find an abstraction that makes your code easier to read/maintain, then go for it!

Daren Thomas
+6  A: 

This is exactly one of the scenarios extension methods are able to solve. You need functionality that isn't already available on a type over which you have no control.

As far as duplicating the code in each of your projects, what you need to do is create a class library project to store your common/shared code like this and then either include that project in each Solution and use project references or compile the project, put the resulting assembly in a shared location and include it as a file project reference.

Remeber that extension methods are only available when they are "brought in to scope". This means that if you have an extension method defined as:

namespace CustomExtensions
{
    public static class StringExtensions
    {
       public static string InvariantToString(this int value)
       {
          return value.ToString(System.Globalization.CultureInfo.InvariantCulture);
       }
    }
}

It will not be visible on any string values unless the code file includes the CustomExtensions namespace with a using directive.

For this reason, it is recommended that you do not put your own extensions in a .NET Framework defined namespace but rather use your own namespace. Doing that minimizes the potential for confusion because your extension won't be available unless it is explicitly brought in to scope.

Also, keep in mind that if you provide an extension method with the exact same signature as a "built-in" method, your extension method will never be visible or callable - the built-in method always takes precedence. If Microsoft decides to include that functionality in a later version of the Framework and uses the exact same signature you chose then your extension method will no longer be called.

When you define an extension method you aren't actually redefining the underlying type being extended so you don't have your own "individual versions". All an extension method provides is a convenient and more natural way to call a static method in a static class. In fact, using my example extension method above, these are equivalent calls:

int i = 42;
Console.WriteLine(i.InvariantToString());
Console.WriteLine(StringExtensions.InvariantToString(i));

While Microsoft does put a lot of thought in to what to include or not include in the Framework, they have no way of knowing about specific use-cases that might be driving your particular need for certain functionality. Yes, most of the time they do a great job and provide functionality "out of the box" but other times they don't. (A good example is missing an InvariantToString() method.)

Scott Dorman
Thanks for the suggestion. That's kinda what I mean by "slippery slope." Microsoft put a lot of thought into what to include and exclude from the framework. Isn't it possible that having my own individual versions of things that are already in the framework will confuse other developers who work with my code? Also, what if Microsoft decides to include the "missing" functionality, or something similar, in the next version of the framework?
John M Gant
@jmgant: Updated my answer to address your other questions/concerns.
Scott Dorman
Good points, and thanks for the extended explanation. I'm convinced that it's OK to do my extension method. The only other thing I might worry about would be if Microsoft implemented a new overload that matched the signature of my extension method but did something different from what mine is doing, an existing application that relied on my version might behave unexpectedly if it was upgraded to the new version of the framework. Probably not likely enough to worry about, but possible.
John M Gant
@jmgant: Yes, it's possible that Microsoft could implement a new overload which matches the signature of your extension method that provides different behavior. If that were to happen, your extension method would no longer be called, which could cause unexpected behavior. While it's possible, it is unlikely that this would happen and should be caught during any testing performed when upgrading framework versions.
Scott Dorman
+1  A: 

Think about the answers to the following issues, then go ahead and create your extension method. Making your work easier is the reason extension methods are part of the language.

  1. You should wrap the extension methods into a namespace specifically for these extensions, so they can be included or excluded at the whim of the developer.
  2. Placing these extensions into a separate dll would allow you to reuse them without copying files or code between projects.
  3. Don't forget to think hard about the design. If others will be using it, you want to polish it up a bit and make sure they can use it quickly and easily. This is also the kind of feature that could cause performance issues, so design it in a way that will allow you to make performance tweaks without changing the usage of the extension methods.
John Fisher
A: 

Well, in Java the option would be to download and compile your own JRE. Or extend the class through inheritance. Now reconsider, aren't Extentension Methods the best you could use in your situation?

I also would recommend creating your own "MyNiftyLibrary" to store this code into. It's the place where I store all my "StringHelper", "...Helper" code. Think of it as your personal .NET AddOn.

Marcel J.
+1  A: 

Extensions are syntactic sugar. Essentially all you're doing is creating some static methods just like any other static method out there... with one exception, they save you a little more typing.

That said, if you (and your team if you have one!) determine that some Extension methods would save you (and your team) time and effort, then add them!

Caveats to this idea:

  • make sure to name your methods something that doesn't get them confused with other framework functionality. (an extension method like: Stream ToStream(this object o) would certainly be annoying!)
  • Watch that you don't add so many that they clutter up your intellisense and slow you down! If that becomes the case, then just leaving them as static methods is probably okay.
  • Only add them if it's something you use a lot on that Type in your environment. For example I have a GraphicsPath.Serialize() extendor for our environment because I almost always have to serialize my GraphicsPaths for what we're working on, and I do it a lot. Otherwise a simple call to my serializer class would've sufficed.
  • DON'T FORGET that if you have an Extension Method for your own internal classes, and someone creates a method on that class with the same name, your Extension will get trumped!
blesh