views:

274

answers:

6
+2  Q: 

C# Extensions

I typically use extension methods very sparingly. When I do feel compelled to write an extension method, I sometimes want to overload the method. My question is, what are your thoughts on extension methods calling other extension methods? Bad practice? It feels wrong, but I can't really define why.

For example, the second CaselessIs method calls the first:

public static bool CaselessIs(this string s, string compareTo)
{
    return string.Compare(s, compareTo, true) == 0;
}

public static bool CaselessIs(this string s, IEnumerable<string> compareTo)
{
    foreach(string comparison in compareTo)
    {
        if (s.CaselessIs(comparison))
        {
            return true;
        }
    }

    return false;
}

Would it be more appropriate to not do this? The downside would be that it violates DRY.

public static bool CaselessIs(this string s, string compareTo)
{
    return string.Compare(s, compareTo, true) == 0;
}

public static bool CaselessIs(this string s, IEnumerable<string> compareTo)
{
    foreach(string comparison in compareTo)
    {
        if (string.Compare(s, comparison, true) == 0)
        {
            return true;
        }
    }

    return false;
}
+3  A: 

I personally don't see a problem with it, the second scenario I think feels more wrong....

Mitchel Sellers
+9  A: 

I would have to say that DRY controls here. Personally, I see nothing wrong with an extension method calling another extension method, especially if that other extension is contained within the same assembly. All-in-all, the method calls are just translated by the compiler from:

extended.ExtensionMethod(foo);

to:

StaticType.ExtensionMethod(extended, foo);

I don't see any problem chaining two static methods together, so transitively, I don't see a problem with chaining two extension methods.

Marcus Griep
+1  A: 

I have no problem with it, myself - though, if it makes you feel better, you could certainly use the static version instead:

public static bool CaselessIs(this string s, IEnumerable<string> compareTo)
{
   foreach(string comparison in compareTo)
   {
      if (Extensions.CaselessIs(s, comparison))
      {
         return true;
      }
   }

   return false;
}

Personally, in this example, I would've called it CaselessMatches, and had the singular call the plural...but that's just nitpicky, I suppose.

Mark Brackett
+2  A: 

Perfectly right. Why should it be wrong?

As you're defining an extension method you're implictily targeting the 3.0 framework (actually the compiler extensions of the new languages) so there's nothing wrong about using just another extension to do the work.

Reviewing the comments there's nothing wrong with any version, not even if the "other" extension was in another library, at least not in the sense of "using" an extension from another one. Extensions are just a syntax feature which helps to better understand the underlying logic between the code, adding some usual operations to a class... in reality they are just masked calls to methods and in that way you should apply exactly the same restriction you use with method calls.

Jorge Córdoba
+1  A: 

I see nothing wrong with it. Let's say you create a someClass.ToMySpecialString(). Why shouldn't you be able to overload it if someClass.ToString() already has multiple overloads?

Kon
A: 

Here are the design guidelines for LINQ, which include extension methods. They don't cover your scenario specifically, but I don't see anything wrong with it.

Daniel Plaisted