Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why to use extension methods if source code is available instead of inheritance [closed]

I just read in msdn/books that extension methods are useful to add methods to existing classes if the existing class source code is not available , however I have noticed in some very good written open source codes that extension methods are still used along with with inheritance (abstract, interface) on classes that have source code written by the author himself/herself.

This is just general question , no source code here.

like image 417
Zara_me Avatar asked Jan 18 '13 12:01

Zara_me


2 Answers

A common reason is dependency management: Let's say you have a fairly general class User and a not-so-general class GravatarImage. Now it might make sense to be able to call SomeUser.GravatarImage() instead of GravatarImage.ImageForUser(SomeUser). This is not only convenience; in a large project, it might be hard for other programmers to find out the 'right' way to do something. IntelliSense will help a lot here.

However, the User class is a "backend" class and should not need to know anything about images, views, gravatars or URLs, so you want to keep dependencies clean.

A similar argument applies to LINQ, which basically consists of extension methods. These extension methods, extend the collection interfaces, so you can create a lot of functionality with very small interfaces. Implementing a new kind of IEnumerable is very easy, yet you gain all the functionality that is provided by LINQ.

The IEnumerable interface, to stick to the example, doesn't allow much more than getting an enumerator. Instead of asking each implementor to provide a Count method, you can call the extension method which will accomplish the same.

It is noteworthy, however, that a method like IEnumerable.Count() can be very slow (it has to touch every element), whereas a direct implementation of the underlying class could be as simple as returning a simple int.

like image 93
mnemosyn Avatar answered Oct 15 '22 07:10

mnemosyn


A lot of the answers already here are great: I love using extensions for optional behavior, and on interfaces. There are a couple of other good reasons.

Avoiding abstract method overloads. Consider the following interface:

public interface IUserService
{
    User GetUser(int userId);
    User GetUser(int userId, bool includeProfilePic);
}

We can see how it might be useful to optionally include the profile pic when getting a user from a IUserService. But, with both methods on the interface, they could be implemented in totally different ways (something this simple probably wouldn't, but I run across this problem a lot). Using extension methods, overloads cannot have divergent behavior:

public interface IUserService
{
    User GetUser(int userId, bool includeProfilePic);
}

public static class UserServiceExtensions
{
    public static User GetUser(this IUserService userService, int userId)
    {
        return userService.GetUser(userId, false);
    }
}

Respect encapsulation. If you have a bit of additional functionality that you want to put on a class, but it does not need any access to internal members of the class to function, and holds no state, then using an extension method is desirable. The fewer things that know about a classes internal members and state the less coupling you will have, and the easier it will be to maintain code in the long run.

A downside: you can't Moq Extension Methods A lot of times this doesn't matter. It means that, in order to mock out behavior behind an extension method, you usually need to know how the extension method works, and mock the virtual methods it calls. This couples your tests to an implementation of the extension method. This is just annoying if your extension method is simple and unlikely to ever change. This is pretty bad if your extension method encapsulates some complex set of calls. For that reason, I usually only use extension methods for relatively simple behaviors.

like image 28
tallseth Avatar answered Oct 15 '22 08:10

tallseth