tags:

views:

103

answers:

4

Although my question is about C# in general, I'll ask it by giving a concrete example.

I have written a function EnsureDirectoryPresent, which is an extension of the System.IO.Directory class in .NET's BCL library. Where can I best put this new function?

Conceptually the method is an extension method to the Directory class. Regrettably, it is a static class, so I cannot use the feature.

A: 

Extension methods only extend instance methods. You cannot extend class's static methods. The reason is static methods are on the type itself when assembly is loaded onto memory so really you cannot extend them.

Also extension method is more of a compiler/IDE/Language feature than the framework.

UPDATE

I got a negative here - unwarrantedI believe - but here is the clarification:

Extension methods are achieved by using static methods, but you access them from your objects not from the type. Hence the first parameter is always "this".

Aliostad
I believe this is incorrect. You can only extend static methods, never instance methods. http://msdn.microsoft.com/en-us/library/bb383977.aspx
Sergio
Yes, you achieve them by using static methods, but you access them from your objects not from the type.
Aliostad
When you replace the word 'methods' with 'classes', his answer makes more sense. You can't put an extension method on `Dictionary`, because that type is static.
Steven
+3  A: 

The .NET Framework Design Guidelines (2nd edition) say to put in a class (or classes) in a child namespace (e.g. "...Extensions"). This is to allow the programmer to control usage, not having the using directive will block extensions that might not be desired:

DO NOT put extension methods in the same namespace as the extended type unless it is for adding methods to interfaces or for dependency management. Of course, in the latter case, the type would be in a different assembly.

However the framework breaks the spirit of this guideline in places (e.g. System.Xml.XPath.Extensions class would be in scope if you were using XPathDocument etc. and then starting using XML to LINQ).

Richard
+1 for quoting the FDG. Please note that, because the `Directory` class is static, it is (currently) impossible to create an extension method for it (for use in C#).
Steven
@Steven: Of course, the answer is to extend `DirectoryInfo`.
Richard
@Richard: The approach taken by one project (http://www.codeproject.com/KB/cs/ntfsstreams.aspx) is to combine extension methods for the Info class with non-extension static helpers for the path string into a single class. (Please let me know if that was unclear.)
Steven Sudit
+2  A: 

You can't extend System.IO.Directory, as it is a static class. But you can extend System.IO.DirectoryInfo - this is a non-static counterpart to System.IO.Directory.

Then you'll be able to use it like this:

(new DirectoryInfo(@"C:\Foo\Bar\Baz").EnsureDirectoryPresent();
Nevermind
You cannot extend it because there is no point! You cannot create an instance of it to use the feature of extension methods. As I explained, extension methods will be used on the instance, no point having that on a type that you cannot have an instance of.
Aliostad
@Aliostad: I don't understand what you're trying to complain about. Are you saying it's not useful to add extension methods to an Info class?
Steven Sudit
@Aliostad - the extension method here is on `DirectoryInfo`, of which you can have instances of. The example looks fine to me.
Alex Humphrey
It does. The point I was trying to get at was regarding Dictionary -as the question was how to extend that.
Aliostad
@Aliostad That's exactly what I meant by "You can't extend System.IO.Directory, as it is a static class."
Nevermind
@Nevermind: Cool then...
Aliostad
+1  A: 

You've worked out that you can't use extension methods to tack on a static method to the Directory class. The next best thing in my opinion would be to simply create a new static class for directory related functions. Typically the Utils suffix is used. I think this is the simplest thing you could do.

static class DirectoryUtils
{
    public static void EnsureDirectoryPresent(string dir) { }
}

DirectoryUtils.EnsureDirectoryPresent(someDirectory);

The only difference in terms of syntax there (as opposed to a static method of the same name in Directory) is the text 'Utils'. However, 'discoverability' is not the same as using an extension method - you have to know about the DirectoryUtils class.

Alex Humphrey