una que programacion método metodos metodo matematicas llamar herencia genérica extensión estática ejemplos definirse debe clases clase c# extension-methods

c# - método - que es un metodo en programacion



¿Hay un impacto en el rendimiento para crear métodos de Extensión que operan fuera del tipo ''objeto''? (4)

Tengo un conjunto de métodos de extensión que uso regularmente para varias tareas de UI. Por lo general, los defino para que se ejecuten fuera del tipo de object , aunque dentro de ellos normalmente los convierto a tipos de cadena.

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. }

La razón principal por la que uso el tipo de object y no la string es para evitar que la interfaz de usuario tenga que hacer <%#Eval("Phone").ToString().FormatSomething()%> cuando puedo hacer <%#Eval("Phone").FormatSomething()%> lugar.

Entonces, ¿está bien desde el punto de vista del rendimiento crear todos los métodos de extensión en un object , o debo convertirlos en tipos de string (o relevantes) según lo que esté haciendo el método de extensión?


¿Hay un impacto en el rendimiento para crear métodos de extensión que operen fuera del tipo de objeto?

Sí. Si pasa un tipo de valor, entonces el tipo de valor será encuadrado. Eso crea una penalización de rendimiento al asignar el cuadro y hacer la copia, y, por supuesto, más tarde tener que recoger el cuadro de basura.

En lugar de

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

Yo escribiría

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

Eso tiene el mismo efecto, pero evita la penalización del boxeo. O, más bien, intercambia una multa por boxeo por una multa por costo de jitting de primera llamada .

¿Está bien desde el punto de vista del rendimiento crear todos los métodos de extensión en un objeto?

No podemos responder a la pregunta. ¡Intentalo! Mida el rendimiento, compárelo con el rendimiento deseado y vea si cumplió con su objetivo. Si lo hiciste, genial. Si no es así, usa un generador de perfiles, encuentra la cosa más lenta y arréglala.

Pero ninguna pregunta es la pregunta que deberías estar haciendo. La pregunta que deberías haber hecho es:

¿Es una buena práctica de programación crear un método de extensión que extienda todo?

No. Casi nunca es una buena idea. En la mayoría de los casos donde las personas quieren hacer eso, están abusando del mecanismo del método de extensión. Típicamente hay algún tipo más específico que podría extenderse. Si haces esto mucho, terminas con muchos métodos de extensión en cada tipo, y la codificación se vuelve confusa y propensa a errores.

Por ejemplo, suponga que desea tener un método de extensión que responda a la pregunta "¿contiene esta secuencia este valor?" Podrías escribir:

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

y luego decir

if (myInt.IsContainedIn(myIntSequence))

Pero es mucho mejor decir:

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

y luego decir

if (myIntSequence.Contains(myInt))

Si lo hace de la primera manera, entonces está escribiendo a lo largo del IDE y cada vez que escribe ".", IsContainedIn le IsContainedIn como una opción porque tal vez esté a punto de escribir un código que determine si este objeto está en Una colección. Pero el 99% de las veces, no vas a hacer eso. Hacer esto agrega ruido a las herramientas y hace que sea más difícil encontrar lo que realmente quiere.


Comparado con cuando se llama a ToString antes de la llamada a FormatAlgo que en realidad no es así (su comprobación de nulos puede demorar algunos ms, pero también hacen que el código sea más sólido.

Incluso si el tipo de tiempo de compilación del objeto en el que está llamando el método fuera una cadena, todavía haría una diferencia visible.

No se preocupe por el rendimiento hasta que tenga un problema de rendimiento. Hasta entonces preocuparse por la mantenibilidad incluyendo la legibilidad. Si tiene un problema de rendimiento, utilice un generador de perfiles para encontrar dónde está.


Dudo seriamente que existan implicaciones de rendimiento fuera de tal vez algún impacto de IDE. Una vez compilado no esperaría que hiciera alguna diferencia.