2009-05-22 22 views
88

Ha habido ocasiones en las que me gustaría sobrescribir un método en una clase con un método de extensión. ¿Hay alguna manera de hacer eso en C#?¿Hay alguna forma en C# para anular un método de clase con un método de extensión?

Por ejemplo:

public static class StringExtension 
{ 
    public static int GetHashCode(this string inStr) 
    { 
     return MyHash(inStr); 
    } 
} 

Un caso en el que he querido hacer esto es ser capaz de almacenar un hash de una cadena en una base de datos y tienen el mismo valor de ser utilizado por todas las clases que use el hash de la clase de cadena (es decir, el diccionario, etc.) Dado que el algoritmo de hash .Net incorporado no garantiza que sea compatible desde una versión del Framework al siguiente, quiero reemplazarlo por el mío.

Hay otro caso en el que me he encontrado donde quiero anular un método de clase con un método de extensión, así que no es solo específico para la clase de cadena o el método GetHashCode.

Sé que podría hacer esto con una subclasificación de una clase existente, pero sería útil poder hacerlo con una extensión en muchos casos.

+0

Como un diccionario es una estructura de datos en memoria , ¿qué diferencia hace si el algoritmo hash cambia de una versión del framework a la siguiente? Si la versión del marco cambia, obviamente la aplicación se ha reiniciado y el diccionario ha sido reconstruido. –

Respuesta

83

No; un método de extensión nunca tiene prioridad sobre un método de instancia con una firma adecuada, y nunca participa en el polimorfismo (GetHashCode es un método virtual).

+0

"... nunca participa en el polimorfismo (GetHashCode es un método virtual)" ¿Podría explicar de otra manera por qué un método de extensión nunca participaría en el polimorfismo debido a que es virtual? Tengo problemas para ver la conexión con esas dos afirmaciones. – Alex

+3

@Alex mencionando virtual. Simplemente estoy aclarando qué significa ser polimórfico. En prácticamente todos los usos de GetHashCode, el tipo concreto es desconocido, por lo que el polimorfismo está en juego. Como tal, los métodos de extensión no ayudarían ** incluso si tuvieran prioridad ** en el compilador regular. Lo que el OP realmente quiere es parchear monos. Qué C# y .net no facilitan. –

+3

Eso es triste, en C# tantos métodos engañosos sin sentido, como p. Ej. '.ToString()' en matrices. Definitivamente es una característica necesaria. –

6

Si el método tiene una firma diferente, entonces se puede hacer, por lo que en su caso: no.

Pero, de lo contrario, necesita utilizar la herencia para hacer lo que está buscando.

2

Hasta donde yo sé, la respuesta es no, porque un método de extensión no es una instancia. Es más como un recurso intellisense que me permite llamar a un método estático usando una instancia de una clase. Creo que una solución a su problema puede ser un interceptor que intercepta la ejecución de un método específico (por ejemplo, GetHashCode()) y hacer otra cosa. Para usar dicho interceptor (como el que proporciona Castle Project) todos los objetos deben ser instalados usando una fábrica de objetos (o un contenedor IoC en Castle) para que sus interfaces puedan ser interceptadas a través de un proxy dinámico generado en tiempo de ejecución. (Caslte también permite interceptar miembros virtuales de clases)

Cuestiones relacionadas