I m a great fan of csharp 4..
i have added too much methods to string object (.net types) as an extension method
consider approximately 200
will that degrads performance?
is it right to add these much methods in .nets library ?
how actually extension methods work internally..?
Well, It is not going to affect runtime performance anyway. Since "Extension Methods" are just compiler trick. Under the hood they are just a static methods in a static class.
public static class MyExt
{
public static void MyExtension(this object obj)
{
//Do something
}
}
public static void Main()
{
object obj = new object();
obj.MyExtension();
//Above line gets compiled into MyExt.MyExtension(obj);
}
As you can see obj.MyExtension(); gets compiled into MyExt.MyExtension(obj); and it is just a method call only. No need of worrying about performance.
If at all you're worried about performance I'd say it won't hurt "runtime performance" though it may or may not hurt compile time performance, Compiler needs to find whether any extension method defined in current namespace as well as imported namespaces.
That is not going to be hard though, since compiler needs to check only static classes. No library is going to have numerous "static classes".
There are no performance penalties for using extension methods, however there is such a thing as bad extension method design. There is a great article about the do's and don'ts of extension methods here: The DOS and DONTS of extension methods.
Related
A contractor where I work is using extension methods to implement CRUD on well-known internal classes that we own. I say it is better to use normal inheritance over extension methods for the following reasons.
Using extension methods obfuscates, hides & confuses the source of the CRUD methods.
I assume extension methods make heavy use of reflection (which is slower).
His logic is, "It's compiled, so it's fast." Maybe I'm wrong...but just because it is compiled doesn't mean it doesn't use reflection, nor does it mean it is faster than normal inheritance.
So my questions are:
How do extension methods work under-the-hood?
Is it better to use inheritance or extension methods on WELL-KNOWN classes that you OWN?
How do extension methods work under-the-hood?
They're just static methods; the compiler rewrites calls like myObject.MyExtensionMethod() to MyExtensionClass.MyExtensionMethod(myObject).
Is it better to use inheretance or extension methods on WELL-KNOWN classes that you OWN?
There's not single answer to this question, it all depends on the context. But usually extension methods are most useful in those cases:
you don't own the code for the extended type
the method targets an interface and will be the same for all implementations of this interface (e.g. IEnumerable<T> and Linq extension methods)
I assume extension methods make heavy use of reflection (which is slower).
No. Extension methods are resolved at compile-time, no reflection required.
That negates your performance concerns.
Is it better to use inheretance or extension methods ?
I would say neither. Use a Repository (DAL). An entity should be persistence-agnostic (so: no inheritance from a base that does CRUD) and not pretend to be involved where it's not (no extensions).
You are right that "Using extension methods obfuscates & confuses the source of the CRUD methods" but inheritance is not the solution.
Description
Extension Methods is a language feature. The compiler makes regular IL (aka MSIL or CIL) code from that. No reflection required.
More Information
MSDN - Extension Methods
Wikipedia - Common Intermediate Language
Your question and the existing answers to it are all missing the bigger picture. New developers joining an on going project should conform to the existing coding styles and standards even if they're not the new persons preferred choices.
If a change in approach represents a major functional improvement as opposed to a primarily esthetic difference it should still be discussed and approved by the entire team first.
Once that's done the change should either be mass implemented and the style guide updated to only contain the new approach, or the old approach should be marked as deprecated and modernized as the code containing it is touched. In the latter case it's best to do commit the cleanup changes separately from the addition/removal/modification of existing functionality so that why the individual modifications in the diff were made is kept clear.
In answer to the first question:
Under the hood, extensions act as Delegates, such that void MyExtension(this object obj) could be rewritten as Action MyDelegate. Where they differ, though, is in syntax when called, as Action must wrap around the object, whereas extensions can be called as if it were a member of the object itself, even though under the hood it is not (nor does it have any direct access to private or protected members of the object, for that matter).
In answer to the second question:
I usually reserve extensions for either classes I do not own or Interfaces.
For example, say you have an interface IAnimal
Public Interface IAnimal
{
void Speak();
void RunToOwnerWhenCalled();
}
And the following classes
public class Mammal
{
public virtual void AnswerWhatAmI()
{
Console.WriteLine("I'm a mammal");
}
}
public class Dog:Mammal, IAnimal
{
public void Speak()
{
Console.WriteLine("arf");
}
public void RunToOwnerWhenCalled()
{
Console.WriteLine("Comming");
}
}
public class Cat:Mammal, IAnimal
{
public void Speak()
{
Console.WriteLine("meow");
}
public void RunToOwnerWhenCalled()
{
Console.WriteLine("I don't know you");
}
}
Then you could have an extension like
Public static void CallAnimal(this IAnimal animal)
{
animal.RunToOwnerWhenCalled();
}
And a method like
Public static void Main
{
Cat cat = new Cat();
cat.CallAnimal();
}
and the result would show the cat's response "I don't know you" in Console.
Consider one more class
Public class Human:Mammal
{
Public Human():base()
{
Console.WriteLine("To be more specific, I am a human.");
}
}
This class wouldn't have the CallAnimal extension, as it does not impliment the IAnimal interface, even though it is a type of Mammal.
Under the hood, an extension method is just like a regular method, and the object it's called on is passed as the first parameter (the this parameter). There's nothing special about an extension method, it's just syntax candy.
It's good practice to avoid extension methods whenever you can. They make the code less readable and less object-oriented.
If it's a class you own, I see no reason to add an extension method to it.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
extension method requires class to be static
In .NET:
Why can't static method in non-static class be an extension method?
Eric Lippert will probably weigh in with a really good answer on this one, but the gist of it will probably be:
We decided it would be easier on both programmers and the compiler if we limit the number of places that you have to look for extension methods.
This policy tends to force users to put all of their extension methods into a few specific classes that are designated for this purpose.
It makes sense that a static class is required to have extension methods. The number one reason is that the static class is stateless ...i.e. you don't have to instance the class. ...but this is just my gut feeling. It wouldn't make sense to me otherwise.
I think, too, that forcing extension methods to reside in public/internal static classes reduces the cost of using them.
Because, well, that's the way it is.
My guess would be that allowing static extension methods would complicate the language (every feature adds complexity of one type or another) while adding almost zero benefit. If you are defining a static method on String for example, what's the benefit in doing so when you can simply define your own class with the same static method?
Instance level extension methods are useful because they work on the current state of a type instance. The static method has no context, so it would not provide any utility over a static method defined elsewhere aside from logical grouping (i.e., defining a String.IsNullOrFullOfSomeChar(char c) would logically make sense to belong to the String class, but aside from that there is no advantage. And yes, that would be a horrible method, just an example).
Extension methods came about as a result of LINQ. They were implemented to get LINQ working the way that the designers wanted. Static extensions were not required and, as such, they were not implemented.
At compile time whenever you use the instance syntax sugar for extension methods, this is converted into a call to the static method (which defines the extension), and passes through your instance.
Apart from the nice syntax it's no different to implementing a static method and passing your instance through as an argument. This is exactly what happens. You can't do this with static classes, as you can't pass a static class as a parameter to a method.
I know from this question that extension methods can only operate on class instances, not the static class itself. This means I can't extend useful static classes like Convert and Math.
What I want to know is, why is this the case? From the link above, there are some suggestions on how the C# team could have implemented this kind of functionality. Is there some philosophical reason why it isn't supported?
For example, here's a rationale behind why there is no built-in LINQ ForEach<T> extension for IEnumerable<T>.
the C# team could have implemented this kind of functionality. Is there some philosophical reason why it isn't supported?
There's no technical reason, and no philosophical reason. However, as I often point out, I don't have to provide a justification for not doing a feature. Features aren't cheap; they are extremely expensive and they must not only justify their own cost, they must justify the opportunity cost of not doing the hundred other features we could have done with that budget. We must justify the cost of features to our stakeholders, but we need not justify saving time and effort by not implementing features that don't meet our bar.
In particular, the proposed feature does nothing for LINQ; extension methods were added to make LINQ work. Anything that didn't make LINQ work was very hard to get into C# 3.0; we had a lot of work on the schedule and not much time to do it in. (I was surprised that automatic properties made it in.) Cutting an unnecessary feature before even designing it saved a lot of time and effort that was spent on other things that do make LINQ work.
In short: the suggested feature has never met our bar for net benefit over cost, and we've always had more important features to spend our limited time and effort on.
After reading through the answers, as well as some related questions, I've assembled my understanding of the issue here.
How extension methods work
First, it's important to realize that extensions are just syntactic sugar for static methods.
// Say you have an extension method that looks like this:
class Extensions
{
public static void Extend(this SomeClass foo) {}
}
// Here's how you call it
SomeClass myClass;
myClass.Extend();
// The compiler converts it to this:
Extensions.Extend(myClass);
The method doesn't actually become part of the class. This is why you can't access private members from an extension method. Extension methods change C# syntax only, and do not violate the concept of OOP accessibility. In fact, if you write an extension method and a normal static method that do the same thing, then decompile the MSIL, they are exactly the same.
Why extension methods exist
So if they don't add actual functionality, why have extension methods at all? The answer is LINQ:
// LINQ makes this easy to read
array.Where(i => i&1 == 0).Select(i => i*i);
// Without extension methods, we would have to do it like this
Enumerable.Select(Enumerable.Where(array, i => i&1 == 0), i => i*i);
In a way, all of LINQ is just syntactic sugar, since everything it can do could be written in a clunky, non LINQy way. Obviously the C# team felt that the readability gained by LINQ was worth it, but it begs the question, "why did they stop there?"
Why not other extension types?
Eric Lippert, one of the C# compiler devs, described in a blog post that a huge part of C# 3 was creating all of the constructs necessary for LINQ: "implicitly typed locals, anonymous types, lambda expressions, extension methods, object and collection initializers, query comprehensions, expression trees, [and] improved method type inference." Because the C# team was the most resource-limited team for the 2008 .NET release, additional types of extensions that weren't strictly necessary for LINQ were not included.
The team did consider implementing extension properties in C# 4, and actually wrote a working prototype, but it was dropped when they discovered it would not enable the WPF team as implemented (which was one of the motivators for the feature). Eric Lipper later said they they did consider extension methods for static classes, but could not justify the real-world benefits against the costs of implementation, testing, and maintenance.
A workaround
It is possible to write an extension method that gets close:
public static TResult DoSomething<TType, TResult>(this TType #class)
{
// access static methods with System.Reflection
return default(TResult);
}
// This works, but poorly
typeof(Math).DoSomething();
typeof(Convert).DoSomething();
But it's pretty ugly. It requires reflection, and can't support any kind of intelligent typing, since any Type can call it and that's likely not the intended functionality.
I believe the answer for your question is because it doesn't make any sense to extend with static methods. Main reason behind introducing Extension methods is not extending class which you do not own. Main reason is that it will allow reduce methods nesting in examples like these:
Enumerable.Select(Enumerable.Where(arr, i => i & 1 == 0), i => i*i); // not the best thing I ever read
arr.Where(i => i&1 == 0).Select(i => i*i); // wow, I see! These are squares for odd numbers
That is why there is no such point to have extension methods for static classes.
Extension methods operate on objects, not classes. If you want an extension method to operate on a class, I suppose you could do this:
public static T DoSomething<T>(this T #class)
where T:Type
{
// access static methods via reflection...
return #class;
}
Static extensions are possible in F# :
type Platform =
| Win32
| X64
override this.ToString() =
match FSharpValue.GetUnionFields(this, typeof<Platform>) with
| case, _ -> case.Name.Replace('X', 'x')
type Environment with
static member Platform =
if System.IntPtr.Size = 8 then Platform.X64 else Platform.Win32
Well its not only about not implemented, but it will cause confusion of where the method belongs to? Static extensions were introduced because linq came in later version and only to support linq in easy to code way, static extensions are useful.
Static extensions are useful only to make code more readable. It has no significance at runtime or compile time.
I have often pondered this one... its probably an idiot question but here goes.
Say I have this class:
public class SomeClass
{
public int AProperty { get; set; }
public void SomeMethod()
{
DoStuff(AProperty);
}
}
Is there any advantage to doing this:
public class SomeClass
{
public int AProperty { get; set; }
public static void SomeMethod(int arg)
{
DoStuff(arg);
}
}
The only advantage that is obvious is that I can now access SomeMethod directly.
So is it good practice to make these kind of methods static where a little refactoring will allow or is it a waste of my time?
EDIT: I forgot to mention (and ShellShock's comment reminded me) that the reason I ask is that I use ReSharper and it always makes suggestions that 'Method X can be made static' and so on...
Static isn't evil. Static is evil if used incorrectly, like many parts of our programming toolkit.
Static can be very advantageous. As the accepted answer here points out, static can have a potential speed improvement.
As a general rule if the method isn't using any fields of the class then its a good time to evaluate its function, however ultimately utility methods that can be called without instantiating an object can often be useful. For instance the DirectoryInformation and FileInformation classes contain useful static methods.
Edit
Feel obligated to point out that it does make mocking a lot harder but it is still definitely testable.
It just means you need to think harder about where static methods go, so that you can always test them without needing to rely on a mock/stub. (ie: don't put them on your DTO that requires a persistent connection to the database).
I'll attempt to answer your specific question involving the code sample you provided.
If SomeMethod is only useful in the class it is declared in, I would avoid the static conversion and leave it as an instance method.
If SomeMethod is useful outside of the class it is in, then factor it out of the class. This may be as a static method in a static utility class somewhere. To make it testable, ensure that all its dependencies are passed in to it as arguments. If it has loads of dependencies, you might want to review the design and figure out exactly what it's supposed to be doing - it might be better as an instance method in one of the classes you're passing in to it.
Some people say that static is evil. This is generally because of the pitfalls that mutable static state provides, where variables hang around from the point a static constructor is called to the tear down of an app domain, changing in between. Code reliant on that state can behave unpredictably and testing can become horrendous. However, there is absolutely nothing wrong with a static method which does not reference mutable static state.
For a (very simple) example where a static is evil, but can be converted to a non-evil version, imagine a function that calculates someone's age:
static TimeSpan CalcAge(DateTime dob) { return DateTime.Now - dob; }
Is that testable? The answer is no. It relies on the massively volatile static state that is DateTime.Now. You're not guaranteed the same output for the same input every time. To make it more test friendly:
static TimeSpan CalcAge(DateTime dob, DateTime now) { return now - dob; }
Now all the values the function relies on are passed in, and it's fully testable. The same input will get you the same output.
Static methods make sense, if you should be able to call them without creating an object of the class before. In Java, for example, the Math-Class contains only static methods, because it wouldn't make much sense to instanciate a Math-Class only to do mathematical operations on other objects.
Most of the time it's better to avoid static methods. You should get familiar with object oriented programming - there are lots of good resources out there, explaining all the concepts like static methods, etc.
I think it will depend on the way you want to use the methods. Using a static method is okay if it is used as a common method over a few instances of the class.
For the sake of an example, say you have a string class and two strings A and B. To compare A and B, you can either have a A.CompareTo(B) method or String.Compare(A, B) method.
Please correct me if I am wrong.
No. Static is evil. It tightly couples the caller to the used class and makes it hard to test.
We are currently discussing whether Extension methods in .NET are bad or not. Or under what circumstances Extension methods can introduce hard to find bugs or in any other way behave unexpectedly.
We came up with:
Writing an extension method for types that are not under your control (e.g. extending DirectoryInfo with GetTotalSize(), etc...) is bad, because the owner of the API could introduce a method that hides our extension - and might have different edge cases. For example testing for null in an extension method will automatically translate into a NullReferenceException if the extension method is no longer used due to hiding.
Question:
Are there any other dangerous situations than "hiding" that we are not thinking of?
Edit:
Another very dangerous situation.
Suppose you have an extension method:
namespace Example.ExtensionMethods
{
public static class Extension
{
public static int Conflict(this TestMe obj)
{
return -1;
}
}
}
And use it:
namespace Example.ExtensionMethods.Conflict.Test
{
[TestFixture]
public class ConflictExtensionTest
{
[Test]
public void ConflictTest()
{
TestMe me = new TestMe();
int result = me.Conflict();
Assert.That(result, Is.EqualTo(-1));
}
}
}
Notice that the namespace where you use it is longer.
Now you reference a dll with this:
namespace Example.ExtensionMethods.Conflict
{
public static class ConflictExtension
{
public static int Conflict(this TestMe obj)
{
return 1;
}
}
}
And your Test will fail! It will compile without a compiler error. It will simply fail. Without you even having to specify "using Example.ExtensionMethods.Conflict". The compiler will walk the namespace name and find Example.ExtensionMethods.Conflict.ConflictExtension before Example.ExtensionMethods.Extension and will use that without ever complaining about ambiguous extension methods. Oh the horror!
Some curiosities:
extension methods might be called on null instances; this might be confusing (but sometimes useful)
the "hiding" issue is a biggie if they have different intent
equally, you might get a different extension method with the same name from 2 different namespaces; if you only have one of the two namespaces, this could lead to inconsistent behaviour (depending on which)...
...but if somebody adds a similar (same signature) extension method in a second namespace that your code uses, it will break at compile time (ambiguous)
(edit) And of course, there is the "Nullable<T>/new()" bomb (see here)...
I disagree, the whole point of extension methods is to add your members to black boxed classes. Like everything else there are pitfalls, you must be mindful in naming, implementation and understand the pecking order of the methods.
One breakage we've just found in the MoreLINQ project: if you write a generic extension method, it's impossible to make sure it will work with all types. We've got a method with this signature:
public static IEnumerable<T> Concat<T>(this T head, IEnumerable<T> tail)
You can't use that with:
"foo".Concat(new [] { "tail" });
because of the string.Concat method...
I've used Ruby on Rails for almost as long as I've used C#. Ruby allows you to do something similar to the new extension methods. There are, of course, potential problems if someone named the method the same, but the advantages of being able to add methods to a closed class far outweigh the potential dissadvantage (which would probably be caused by bad design or poor planning).
One thing you can do to make sure extension methods don't conflict with other methods (extension or otherwise) is to use FxCop with rules such as Prevent Duplicate Extension Method Signatures.
First of all I believe your wording is a bit misleading. I take it you're talking about "types" and not "objects".
Secondly, the big advantage of extension methods is that you can add features to type you don't control. If you control the type, why not just modify the type instead of relying on extension methods?
We took the attitude in my team that Extension Methods are so useful that you can't realistically ban them, but so dangerous (principally because of the hiding issue) that you have to be a bit cautious. So we decided that all Extension Method names have to be prefixed with X (so we have a bunch of XInit...() methods to initialise controls in useful ways, for instance). That way a) the likelihood of a naming collision is reduced and b) the programmer knows he is using an Extension Method and not a class method.
What .Net calls extension methods are also a limited form a MonkeyPatching (try to ignore the php rant in there).
That should give you some material for your discussion.