I have a set of extension methods that I regularly use for various UI tasks. I typically define them to run off of type object
, even though inside of them I'm typically converting them to string types.
public static string FormatSomething(this object o) { if( o != null ) { string s = o.ToString(); /// do the work and return something. } // return something else or empty string. }
The main reason I use type object
and not string
is to save myself in the UI from having to do <%#Eval("Phone").ToString().FormatSomething()%>
when I can do <%#Eval("Phone").FormatSomething()%>
instead.
So, is it fine from performance standpoint to create all the extension methods on object
, or should I convert them to be string
(or relevant) types based on what the extension method is doing?
The main advantage of the extension method is to add new methods in the existing class without using inheritance. You can add new methods in the existing class without modifying the source code of the existing class. It can also work with sealed class.
For an application programmer, extension methods are an incredibly powerful and expressive tool. They enable convenience, extensibility, and an improved intellisence experience. However, many of the features that make extension methods so useful for library consumers can be problematic for class library authors.
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are static methods, but they're called as if they were instance methods on the extended type.
As already discussed, any extension method should be static and should have "this" keyword preceding the parameter you want the method to be called on.
Is there a performance hit for creating extension methods that operate off the object type?
Yes. If you pass a value type in then the value type will be boxed. That creates a performance penalty of allocating the box and doing the copy, plus of course later having to garbage collect the box.
Instead of
public static string FormatSomething(this object o) { return (o != null) ? o.ToString() : ""; }
I would write
public static string FormatSomething<T>(this T o) { return (o != null) ? o.ToString() : ""; }
That has the same effect, but avoids the boxing penalty. Or rather, it trades a per call boxing penalty for a first call jitting cost penalty.
is it fine from performance standpoint to create all the extension methods on object?
We cannot answer the question. Try it! Measure the performance, compare that against the desired performance, and see if you met your goal. If you did, great. If not, use a profiler, find the slowest thing, and fix it.
But neither question is the question you should be asking. The question you should have asked is:
Is it a good programming practice to create an extension method that extends everything?
No. It is almost never a good idea. In most cases where people want to do that, they are abusing the extension method mechanism. Typically there is some more specific type that could be extended. If you do this a lot then you end up with lots of extension methods on every type, and coding becomes confusing and error-prone.
For example, suppose you want to have an extension method that answers the question "does this sequence contain this value?" You could write:
public static bool IsContainedIn<T>(this T item, IEnumerable<T> sequence)
and then say
if (myInt.IsContainedIn(myIntSequence))
But it is much better to say:
public static bool Contains<T>(this IEnumerable<T> sequence, T item)
and then say
if (myIntSequence.Contains(myInt))
If you do it the first way then you're typing along in the IDE and every single time you type ".", you get prompted with IsContainedIn
as an option because maybe you're about to write code that determines if this object is in a collection. But 99% of the time, you're not going to do that. Doing this adds noise to the tooling and makes it harder to find what you really want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With