2010-10-14 11 views

Respuesta

49

¿Por qué los métodos de extensión solo se permiten en clase estática no anidada y no genérica?

Como Pratik señala, la pregunta que nos enfrentamos no es "¿por qué son los métodos de extensión no permitidos en clases anidadas o genéricos?" La pregunta que enfrentamos como diseñadores de idiomas es "¿por qué deberían permitirse los métodos de extensión en clases anidadas o genéricas?"

A menos que la función esté justificada por alguna necesidad del usuario en el mundo real, no vamos a asumir los costos considerables de diseñar, implementar, probar, documentar y mantener la función.

Básicamente, los métodos de extensión se diseñaron para hacer que LINQ funcione. Todo lo que no contribuyó a hacer que LINQ funcione fue cortado. LINQ solo necesita métodos de extensión en clases estáticas, no genéricas, no anidadas para trabajar, así que eso es lo que diseñamos e implementamos.

Si tiene un escenario donde los métodos de extensión serían útiles en clases no estáticas, genéricas o anidadas, me complace echarle un vistazo al escenario. Cuantos más escenarios del mundo real obtengamos, más probable será que creemos una función en algún lenguaje futuro hipotético que beneficie esos escenarios.

¿Es inútil considerar los métodos de extensión en la clase estática genérica anidada?

No, es una gran idea para considerarlo. Seríamos negligentes en nuestros deberes si no lo consideramos. Lo consideramos cuidadosamente durante mucho tiempo y decidimos que, sobre la base de esa consideración, los costos de la prestación no estaban justificados por los beneficios acumulados.

+1

OK. Gracias. Buena y clara explicación! Por el bien de LINQ ... – xport

+0

@EricLippert: Encontré este artículo después de intentar crear un método de extensión en una clase no estática y luego en una clase interna estática. Lo hice porque quería crear un método de "instancia" nulo seguro que devolviera un valor predeterminado (en este caso nulo, así que supongo que podría considerarse un caso de acceso de miembro de propagación nula, aunque realmente estaba pensando en desde una vista más genérica). Sería genial si la mayoría, si no todos, de los métodos de Strings fueran así; es probable que ya sea demasiado tarde para eso, pero si hubiera estado disponible al principio ... – jmoreno

+1

posiblemente mi pregunta, que es esencialmente un duplicado de este proporciona un ejemplo del mundo real (?) ... http://stackoverflow.com/questions/11443842/why-not-allow-extension-method-definition-in-nested-class –

3

Creo que esto se hizo para que el compilador pueda localizar/buscar el método de extensión en un tiempo razonable. Además, tenga en cuenta que los métodos de extensión de búsqueda de compilador solo en el conjunto de espacios de nombres que se encuentran en el alcance del archivo, esto también se hace por motivos similares.

Si piensa en un escenario de clase estático genérico, el compilador debe intentar crear una instancia de los tipos concretos para todas las combinaciones de tipos posibles para coincidir con el método de extensión. Incluso si complier puede ser inteligente al hacer esto, instanciar el tipo concreto para llamar a los métodos de extensión puede tener un efecto secundario que el desarrollador puede desconocer.

+0

Sin embargo, todavía podría tenerlos en alcance dondequiera que esté la clase. Es decir, las extensiones de una clase estática anidada estarían dentro del alcance de la clase de ajuste; y, en particular, eso no es problemático, incluso si la clase de envoltura no es estática y genérica. –

+0

He escuchado este argumento (restricción de métodos de extensión a clases estáticas no anidadas, no genéricas para acelerar su descubrimiento) anteriormente, pero ya no estoy tan convencido: sospecho que sería posible identificar muy rápidamente todos los métodos estáticos en un ensamblaje que está decorado con un 'ExtensionAttribute', es decir, escaneando la tabla de metadatos CLI' CustomAttribute' (vea el capítulo II.22.10 de la [especificación CLI (ECMA-335)] (http: //www.ecma-international. org/publications/files/ECMA-ST/ECMA-335.pdf)). – stakx

5

Como Eric Lippert ha escrito muchas veces en su blog, cada cambio a C# se evalúa cuidadosamente contra un conjunto de criterios para justificarlo y no solo por razones de tecnología. En este caso, lo que no se requería para habilitar LINQ se cortó para reducir el riesgo. Compruebe esto blog post de Eric para una pregunta similar.

Cuestiones relacionadas