views:

178

answers:

2

I'm a little confused as to why this doesn't give an error. I found this code deep inside of some outdated legacy software and was surprised to see it work.

public static string CleanFileName(this string fileName)
{
  return CleanFileName(fileName, 64);
}

public static string CleanFileName(this string fileName, int maxLength)
{
  //some logic
}

My experience with extension methods is to call it like this:

fileName.CleanFileName(64);

Does this only work because its a static method as well? Is this common practice and just something I haven't seen yet or a piece of outdated legacy code that I should kill with fire?

+5  A: 

It works because the call to CleanFileName(string, int) is being made from within the same type as CleanFileName(string), which allows the call to be made in standard method syntax, rather than extension method syntax. As such, no string instance prefix is required in front of the extension method.

Semantically speaking, static string Foo(this string foo, int bar) { } can be called in the form of Foo(string, int) or string.Foo(int).

Nathan Taylor
No idea who down voted this, it's the right answer.
DavidWhitney
I am wondering the same thing...
Nathan Taylor
I didn't downvote it, but the answer has nothing to do with whether you are calling it from "inside of the same type".
Kirk Woll
I don't understand what you mean by that? That's exactly what the answer has to do with.
Nathan Taylor
Downvote was when the answer was merely the first sentence, which is so incomplete as to be incorrect. The second paragraph improves upon it, but the simple answer is that extension methods can be called using full Class.Method syntax or via the extension shorthand, being inside or outside of the class has nothing at all to do with it.
Anthony Pegram
@Nathan, you are mistaken.
Kirk Woll
Speaking strictly from good coding standards, are these two ways of solving the same problem? Or is it merely a less ideal working solution?
Aardvark
@Aardvark Personally, I use this method of invoking extensions quite often in my own code when writing HtmlHelpers for ASP.NET MVC.
Nathan Taylor
@Anthony I'm not sure if the verbiage was bad or if something else is the problem, but my answer is fully accurate. Are my revisions more on par with what you would consider to be a valid answer?
Nathan Taylor
Extension methods are syntactic sugar for calling static methods in the ordinary fashion by passing in all the parameters, including the first one. (And in fact invocations to extension methods always compile down to an ordinary static method call)
Kirk Woll
@Kirk I feel that my current answer reflects that fact.
Nathan Taylor
@Nathan, This sentence is false: "It works because the method call is being made **from within the same type as its overload**."
Kirk Woll
@Kirk Please explain how that's wrong?
Nathan Taylor
@Nathan, Beause it's not true? You **do not** have to be invoking the method "from within the same type as its overload".
Kirk Woll
@Kirk While it's true that both overloads are accessible externally, the original statement does hold true in this particular block of code. In any case, I have revised the wording a little and I think it's more accurate now. Thoughts?
Nathan Taylor
But the point is that very same call would work **equally** well if you were *not* in the same type.
Kirk Woll
P.S. I think DoctaJones explained our mutual non-understanding in the comments to my answer. :)
Kirk Woll
!Kirk It would certainly seem as though there was a bit of confusion. I will concede that my initial answer wasn't exactly perfect. I think through our discussion I have shaped it into something more valid though.
Nathan Taylor
+10  A: 

Extension methods can always optionally be called as if the "this" modifier was not even there (aka as a normal static method). It's less readable to do this, but syntactically valid.

The other answer is misleading because "It works because the method call is being made from within the same type as its overload." implies something about extension methods. You can invoke extension methods as normal static methods regardless of what class you happen to be in. But through the comments below, it sounds like the confusion is whether the class needs to be qualified or not. And in that vein, Nathan is correct that the reason the class name can be elided is because the call is happening from within the same class as the overload.

Kirk Woll
I think that the statement that the other answer is "patently false" is incorrect. Within a type, you can call static methods of that type without prefixing the method call with the declaring type. So seeing the call from one extension method from another without the declaring type prefix, within the same type works just like any other static declarations that are not "extensions".
Dave White
Yes, but the **point** is that it has nothing to do with whether you're "within the same type" or not. You can use that syntax from **any** type.
Kirk Woll
I believe Nathan was trying to explain why it is legal to write return CleanFileName(fileName, 64); instead of writing return ClassName.CleanFileName(fileName, 64); This is indeed legal because the call is within the declared type. I also believe that this is the crux of what the OP was asking.
DoctaJonez
Well that interpretation would have nothing at all to do with extension methods, which would seem peculiar. But I do see your point.
Kirk Woll
You can't call `CleanFileName(fileName, 64);` as it is typed out outside of the extension class. Outside of the extension class, that method call must be prefixed with the declaring type such as `string.CleanFileName(fileName, 64);` or on an instance of a string such as `mystring.CleanFileName(64);` I think that was the OP's intent in asking the original question.
Dave White
Kirk's point is also valid about it just being like any regular static method, but I believe the OP was confused as to why it could be called without a class name or an instance prefix.
DoctaJonez
@Dave, sure, but this is true of all static methods, not extension methods.
Kirk Woll
@Kirk I know. I think that is what the OP was asking and he (sorry @Aardvark) didn't understand that it can be treated just like any other static.
Dave White
Extension methods are very cool, but the way they've been implemented leads to so much confusion. It's a bit of a shame.
DoctaJonez
Let me try and clarify my confusion :P I didn't realize that it was being handled as a static, however by watching this thread I learned a whole lot! Thanks both of you for pursuing this so adamantly, it was between your back and forth that I got a really detailed answer. If I could have selected both your answers I would have in a heartbeat. Thanks Dave for speaking newbie for me :)
Aardvark