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

我有一组扩展方法,我经常用于各种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中不必执行当我可以执行代替。

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

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

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

代替

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

我会写的

 public static string FormatSomething(this T o) { return (o != null) ? o.ToString() : ""; } 

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

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

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

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

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

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

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

 public static bool IsContainedIn(this T item, IEnumerable sequence) 

然后说

 if (myInt.IsContainedIn(myIntSequence)) 

但是,最好说:

 public static bool Contains(this IEnumerable sequence, T item) 

然后说

 if (myIntSequence.Contains(myInt)) 

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

我非常怀疑,除了一些IDE影响之外,还会有任何性能影响。 编译后,我不希望它会有任何区别。

与调用ToString时相比,调用FormatSomething并不是真的(你的空检查可能需要几个ms,但它们也会使代码更健壮。

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

在遇到性能问题之前,请不要担心性能问题。 在此之前担心可维护性,包括可读性。 如果您遇到性能问题,请使用分析器查找它的位置。

在运行时与扩展方法相关的开销是多少? (.NET)我想回答你的问题。 扩展方法只是静态方法,因此它们不属于Object类型。 Intellisense只会让它看起来如此。