创建操作类型为'object'的扩展方法是否会影响性能?

本文关键字:是否 性能 方法 影响 object 类型 操作 创建 扩展 | 更新日期: 2023-09-27 18:10:22

我有一组扩展方法,我经常将它们用于各种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的主要原因是,当我可以做<%#Eval("Phone").FormatSomething()%>时,在UI中不必做<%#Eval("Phone").ToString().FormatSomething()%>

那么,从性能的角度来看,在object上创建所有的扩展方法是好的,还是我应该根据扩展方法正在做的事情将它们转换为string(或相关)类型?

创建操作类型为'object'的扩展方法是否会影响性能?

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

是的。如果传入一个值类型,则该值类型将被框起来。这会造成分配盒子和执行复制的性能损失,当然之后还必须对盒子进行垃圾收集。

代替

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() : "";
}

具有相同的效果,但避免了拳击惩罚。或者更确切地说,它用每次调用拳击惩罚换取第一次调用跳跃成本惩罚。

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

我们不能回答这个问题。试一试!衡量绩效,将其与期望的绩效进行比较,看看是否达到了目标。如果你做到了,那很好。如果不是,使用分析器,找到最慢的东西,并修复它。

但这两个问题都不是你应该问的问题。应该问的问题是:

是一个良好的编程实践,创建一个扩展方法,扩展一切?

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

例如,假设您希望有一个扩展方法来回答"这个序列是否包含这个值?"你可以这样写:
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%的情况下,你不会这么做。这样做会增加工具的噪音,并使您更难以找到真正想要的东西。

除了可能对IDE产生一些影响外,我非常怀疑会有任何性能影响。一旦编译,我不期望它会有什么不同。

与在调用FormatSomething之前调用ToString相比,不是真的(您是null)检查可能会花费更多毫秒,但它们也使代码更健壮。

即使你调用方法的对象的编译时类型是字符串,它仍然会产生明显的差异。

在出现性能问题之前不要担心性能。在此之前,要担心可维护性,包括可读性。如果你有一个性能问题,然后使用分析器找到它在哪里。

在运行时与扩展方法相关的开销是什么?(. net)回答了你的问题。扩展方法只是静态方法,因此它们不属于Object类型。智能感知只是让它看起来是这样。