创建以"对象"类型操作的扩展方法是否会影响性能?

Doo*_*ake 27 c# extension-methods

我有一组扩展方法,我经常用于各种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.

}
Run Code Online (Sandbox Code Playgroud)

我使用类型object而不是使用类型的主要原因string<%#Eval("Phone").ToString().FormatSomething()%>在我可以做的时候将自己保存在UI中<%#Eval("Phone").FormatSomething()%>.

那么,从性能的角度来看,创建所有扩展方法是否正常object,或者我应该根据扩展方法的作用将它们转换为string(或相关)类型?

Eri*_*ert 54

创建以对象类型操作的扩展方法是否会影响性能?

是.如果您传入值类型,则值类型将被加框.这会造成分配盒子和进行复制的性能损失,当然后来不得不垃圾收集盒子.

代替

public static string FormatSomething(this object o) 
{
    return (o != null) ? o.ToString() : "";
}
Run Code Online (Sandbox Code Playgroud)

我会写的

public static string FormatSomething<T>(this T o) 
{
    return (o != null) ? o.ToString() : "";
}
Run Code Online (Sandbox Code Playgroud)

这具有相同的效果,但避免了拳击惩罚.或者更确切地说,它对于第一次调用成本惩罚换取每次通话拳击惩罚.

从性能的角度来看,在对象上创建所有扩展方法是否很好?

我们无法回答这个问题.试试吧!测量性能,将其与所需性能进行比较,看看您是否达到了目标.如果你这样做,那很好.如果没有,请使用分析器,找到最慢的东西,并修复它.

但问题不是你应该问的问题.你应该问的问题是:

创建一个扩展所有内容的扩展方法是一种很好的编程习惯吗?

不,这几乎不是一个好主意.在人们想要这样做的大多数情况下,他们滥用扩展方法机制.通常,有一些更具体的类型可以扩展.如果你这么做很多,那么你最终会在每种类型上都有很多扩展方法,而且编码会变得混乱和容易出错.

例如,假设您希望有一个扩展方法来回答"此序列是否包含此值?"的问题.你可以写:

public static bool IsContainedIn<T>(this T item, IEnumerable<T> sequence)
Run Code Online (Sandbox Code Playgroud)

然后说

if (myInt.IsContainedIn(myIntSequence))
Run Code Online (Sandbox Code Playgroud)

但是,最好说:

public static bool Contains<T>(this IEnumerable<T> sequence, T item)
Run Code Online (Sandbox Code Playgroud)

然后说

if (myIntSequence.Contains(myInt))
Run Code Online (Sandbox Code Playgroud)

如果你是第一种方式,那么你在IDE中输入,每次输入"."时,都会提示你IsContainedIn作为一个选项,因为你可能会编写一个代码来判断这个对象是否在采集.但99%的情况下,你不会这样做.这样做会给工具增加噪音,使得找到你真正想要的东西变得更加困难.

  • @STW:是的.对于对象的扩展方法,它特别令人震惊,因为装箱是不明显的.它看起来只是一个值的方法,你会天真地期望不会包装任何东西. (4认同)
  • 所以,要明确的是,你指出的瓶颈并不是特定于扩展方法,而是任何通过引用传递值类型的方法 (3认同)