2011-08-23 26 views
7

Entiendo que los métodos de extensión C# deben ser estáticos. Lo que no entiendo es por qué estas extensiones no se pueden definir en clases no estáticas o genéricas.¿Por qué deben definirse los métodos de extensión C# en clases estáticas?

Actualización: Estoy interesado en el motivo de esta decisión de diseño.

+0

Busco detenidamente el caso de la clase estática antes de hacer esta pregunta y no he encontrado la respuesta que ha mencionado. Por cierto, no es exactamente la misma pregunta y mi respuesta no se encuentra en esa publicación. – Mehran

+0

¿Cómo es esto un * exacto * duplicado de "¿Por qué es imposible declarar métodos de extensión en una clase genérica estática?". –

+0

Esto no es un duplicado. Más bien una pregunta más específica del llamado doble. –

Respuesta

5

Esto es más de una observación de una respuesta, pero ...

Cuando se llama a un método de instancia, una referencia al objeto al que llama se inserta en la pila como primer argumento en su llamada de método Ese primer argumento es "esto" y se hace implícitamente.

Cuando define un método de extensión, define explícitamente "this" como primer argumento.

Es posible que la resolución del método sea confusa si pudiera definir métodos de extensión y métodos de instancia en la misma clase, es decir, definir métodos con el mismo nombre y, en efecto, los mismos parámetros cuando el parámetro "este" incluido.

+0

Esa es una gran observación y también plausible. Gracias por compartirlo. – Mehran

+0

Quizás, excepto que en mi humilde opinión realmente debería haber una gran excepción a la regla: una clase o estructura debería poder definir miembros de extensión que operen con miembros de su propio tipo, y en el caso de las estructuras, debería ser posible para la "este" parámetro es por valor o referencia. Dichos métodos de extensión permitirían que los tipos de clases inmutables se comporten más como tipos de valores con respecto a la inicialización, y permitirían utilizar la sintaxis normal de "métodos" en los mutadores de estructuras sin el riesgo de que se apliquen en contextos de solo lectura. – supercat

+0

@supercat Si pudieras definir un método de extensión en una clase para actuar sobre sí mismo, no sería un método de extensión, ¿verdad? –

1

Porque la especificación lo dice ... Ahora bien, probablemente haya buenas razones por las que escribieron las especificaciones de esta manera.

La razón por la que no se pueden declarar en clases genéricas es bastante obvia: dada la forma en que se llaman los métodos de extensión, ¿dónde se especificaría el argumento de tipo para la clase?

La razón por la que debe ser una clase estática es menos obvia, pero creo que tiene sentido. El caso de uso principal para las clases estáticas es agrupar los métodos de ayuda (por ejemplo, Path, Directory, ProtectedData ...), y los métodos de extensión son básicamente métodos auxiliares. No tendría sentido crear una instancia de Enumerable o Queryable, por ejemplo.

+0

Entiendo lo que dice la especificación. Me interesa saber por qué se toman estas decisiones de diseño. – Mehran

+0

@Mehran, eso es precisamente lo que traté de explicar en mi respuesta ... No repití lo que dice la especificación. –

+1

Los métodos de extensión pública solo tendrían sentido en una clase estática de nivel superior, pero las reglas podrían haber permitido sensiblemente que los métodos de extensión se declararan en clases privadas o protegidas anidadas, con la condición de que tales métodos solo puedan utilizarse cuando sean visibles. Por ejemplo, el código para la clase 'Foo ' podría beneficiarse al poder definir un método de extensión que use un tipo que sea privado para 'Foo '. Tal método de extensión no tendría problemas para saber qué 'T' usar, ya que el único código que podría verlo tendría ese tipo disponible. – supercat

3

echar un vistazo para esta pieza de .NET C# especificación:

Cuando el primer parámetro de un método incluye el este modificador, que se dice método sea un método de extensión. Los métodos de extensión solo pueden declararse en clases estáticas no genéricas y no anidadas. El primer parámetro de un método de extensión no puede tener modificadores distintos de , y el tipo de parámetro no puede ser un tipo de puntero.

y este fragmento de Jon Skeet's answer:

No es claro por qué todas estas restricciones son necesarias - que no sea potencialmente simplicidad de compilador (y especificación del lenguaje). I puedo ver por qué tiene sentido restringirlo a tipos no genéricos, pero I no puede ver inmediatamente por qué tienen que ser no anidados y estáticos. I sospecho que simplifica considerablemente las reglas de búsqueda si no tiene que preocuparse por los tipos que figuran dentro del tipo actual, etc., pero I se atreven a decir que sería posible.

Cuestiones relacionadas