问题描述
我有一套扩展方法,经常用于各种UI任务。我通常将它们定义为以 object
类型运行,即使在它们内部我通常会将其转换为字符串类型。
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.
}
我使用类型的主要原因对象
,而不是字符串
,是为了避免自己不得不在<%#Eval( Phone ).ToString()。FormatSomething()%>
当我可以做<%#Eval( Phone)。FormatSomething()%> $ c
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.
所以,从性能角度来看,可以在 object
上创建所有扩展方法,还是应该根据扩展方法的作用将它们转换为 string
(或相关)类型?
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?
推荐答案
是。 如果在其中传递值类型,则该值类型将被装箱。这会造成分配框和进行复制的性能损失,当然,稍后还要垃圾回收框。
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.
代替
public static string FormatSomething(this object o)
{
return (o != null) ? o.ToString() : "";
}
我会写
public static string FormatSomething<T>(this T o)
{
return (o != null) ? o.ToString() : "";
}
具有相同的效果,但避免了拳击惩罚。或者,它用每次通话拳击罚金换成首次通话 jitting成本罚金。
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.
我们无法回答问题。试试吧!测量性能,将其与所需性能进行比较,看看是否达到目标。如果您做到了,那就太好了。如果不是,请使用探查器,找到最慢的东西,然后修复它。
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.
但这两个问题都不是您应该问的问题。您应该问的问题是:
否。这几乎从来不是一个好主意。在大多数人想要这样做的情况下,他们正在滥用扩展方法机制。通常,可以扩展一些更特定的类型。如果您经常这样做,那么最终每种类型都会有很多扩展方法,并且编码变得混乱且容易出错。
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)
然后说
if (myInt.IsContainedIn(myIntSequence))
但是说起来好得多:
public static bool Contains<T>(this IEnumerable<T> sequence, T item)
,然后说
if (myIntSequence.Contains(myInt))
如果您是第一种方式,则需要在IDE中键入并且每次您键入。,都会提示您使用 IsContainedIn
作为提示,因为也许您将要编写代码来确定该对象在集合中。但是99%的时间,您不会那样做。这样做会增加工具的噪音,并使您更难找到真正想要的东西。
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.
这篇关于创建以“对象”类型操作的扩展方法是否会对性能产生影响?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!