我有一组用于各种UI任务的扩展方法。我通常将它们定义为从object类型运行,即使在它们内部,我通常将它们转换为字符串类型。
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.
}我使用类型object而不是string的主要原因是为了节省我自己在UI中必须执行<%#Eval("Phone").ToString().FormatSomething()%>,而我可以执行<%#Eval("Phone").FormatSomething()%>。
那么,从性能的角度来看,在object上创建所有的扩展方法是可以的,还是应该根据扩展方法所做的事情将它们转换为string (或相关)类型?
发布于 2011-10-05 02:24:37
创建操作对象类型的扩展方法是否会影响性能?
是。如果传入一个值类型,则该值类型将被装箱。这会造成分配盒子并进行复制的性能损失,当然,之后还必须对盒子进行垃圾回收。
而不是
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() : "";
}这有相同的效果,但避免了拳击惩罚。或者更确切地说,它用每次调用的装箱代价来换取第一次调用的代价。
从性能的角度来看,在object上创建所有的扩展方法可以吗?
我们不能回答这个问题。试试看!测量性能,将其与期望的性能进行比较,并查看您是否达到了目标。如果你有,那就太好了。如果没有,使用分析器,找到最慢的东西,并修复它。
但是这两个问题都不是你应该问的问题,你应该问的问题是:
创建一个扩展所有东西的扩展方法是一种好的编程实践吗?
不是的。这几乎从来都不是一个好主意。在人们想要这样做的大多数情况下,他们滥用了扩展方法机制。通常,有一些更具体的类型可以扩展。如果你经常这样做,那么你最终会在每种类型上使用大量的扩展方法,并且编码变得令人困惑和容易出错。
例如,假设您想要一个扩展方法来回答“这个序列包含这个值吗?”这个问题。你可以这样写:
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))如果你使用第一种方法,那么你就是在集成开发环境中输入,每次你输入".“时,你都会得到一个IsContainedIn选项的提示,因为你可能要编写代码来确定这个对象是否在集合中。但99%的情况下,你不会这么做。这样做会增加工具的噪声,并且更难找到您真正想要的东西。
发布于 2011-10-05 02:03:43
我严重怀疑除了一些IDE影响之外,是否会有任何性能影响。一旦编译好了,我想它不会有什么不同。
发布于 2011-10-05 02:18:23
与之前调用ToString时相比,对FormatSomething的调用并不是真的(您是空的,检查可能需要更多毫秒,但它们也使代码更健壮。
即使调用该方法的对象的编译时类型是string,它仍然会产生明显的差异。
在遇到性能问题之前,不要担心性能问题。在此之前,要考虑可维护性,包括可读性。如果你有一个性能问题,那么使用一个分析器来找出它在哪里。
https://stackoverflow.com/questions/7652118
复制相似问题