2009-02-11 13 views

Respuesta

3

No creo que haya una buena razón. Cualquier implementación de GetHashCode debe ser lo suficientemente rápida como para poner en una propiedad. Dicho esto, hay plenty of design flaws en .Net framework, algunos pequeños, otros serios. Esto parece pequeño.

+10

Según los lineamientos especificados en las Pautas de diseño del marco, si el cálculo es "costoso" debería ser un método, no una propiedad. Como el cómputo de código hash es completamente desconocido para los objetos personalizados en lo que respecta al Marco, es mejor como una función. –

19

Probablemente porque requiere un cálculo, y exponerlo como propiedad podría implicar que el código hash ya está disponible de forma gratuita.

Editar: Directrices sobre esto: Properties versus Methods

"La operación es bastante caro que desea comunicar al usuario que deberían considerar el almacenamiento en caché el resultado."

Quizás GetHashCode sea lo suficientemente caro en algunos casos.

+0

Gracias, ¿hay alguna pauta para no tener propiedades que requieran computación? La razón por la que pregunto es que he visto muchas cosas que se computan cuando accede a la propiedad. –

+1

@Joan, a veces puede ser lento generar un buen Hashcode –

0

propiedades sólo se deben usar si el cálculo detrás de ellos es muy rápido o en caché

además de la mayor parte del tiempo la única lógica en las propiedades de validación debe ser

-2

Hay que recordar que el .NET Framework es diseñado para ser accedido por una amplia variedad de idiomas.

En teoría, podría crearse un compilador que no puede anular correctamente las propiedades. Si bien eso sería un buen compilador, no sería necesariamente ilegal. (Recuerde que las propiedades son solo métodos con algunos metadatos)

+1

También podría hacer un compilador que no puede anular los métodos. Y muchos otros.Las interfaces NET requieren que se sobrepase una propiedad. – MichaelGG

+1

Muchas interfaces requieren anular una propiedad, pero Object es el abuelo de todo, ¿por qué no mantenerlo simple? – Guvante

1

Además de que una propiedad no es más que un getter y un método setter, desde el punto de vista del diseño una propiedad nunca debe contener cálculos distintos de la inicialización o validación, p. Ej .:

private object _obj; 
public object Obj 
{ 
    get 
    { 
    if(_obj == null) 
    { 
     _obj = new object(); 
    } 
    return _obj; 
    } 
    set 
    { 
    if(value == badvalue) 
    { 
     throw new ArgumentException("value"); 
    } 
    _obj = value; 
    } 
} 

GetHashCode() no contiene cálculos extensos, pero podría contener tales operaciones de larga ejecución (sólo por el hecho de que se podía calcular el código hash de un objeto de una manera compleja), es por eso que es un método en lugar de una propiedad.

2

A menudo no es posible definir un HashCode para una clase que hace desde:

por ejemplo los objetos de la clase no tienen un concepto bien definido de identidad .

Por lo tanto, es común hacer que el método GetHashCode() arroje una NotImplementedException. Esto resolvería todo tipo de problema si HashCode fuera una propiedad, ya que la mayoría de las personas (y depuradores) asumen que siempre es válido obtener el valor de una propiedad

+1

Casi todos los objetos de clase generalmente deben tener semántica de referencia o semántica de valores inmutables. Los objetos con semántica de referencia tienen un concepto claro de identidad (el objeto X y el objeto Y son iguales si y solo si X e Y se refieren al mismo objeto). Los objetos con semántica de valores inmutables tienen un concepto claro de identidad (el objeto X y el objeto Y son iguales si tienen valores iguales). ¿Qué tipos de objetos no tienen un concepto de identidad bien definido? – supercat

+0

@supercat, Equals solo debe devolver true para objeto con el mismo HashCode, sin embargo, a menudo veo un método equals definido solo para el uso de pruebas unitarias en obejct que no son inmutables. Entonces, para detener la advertencia del compilador, se debe anular GetHashCode(); sin embargo, sepa que el objeto nunca debe usarse como clave. Sin un método útil igual en los objetos, los activos en las colecciones en nUnit no funcionan. –

+0

Eso sería un abuso definitivo de Object.Equals(). En realidad, me gustaría que el método se llamara Equivalente(), en lugar de Equal(), ya que es el concepto de equivalencia, más que el nombre, el que es universalmente aplicable, y en algunos casos podría ser útil para algunos objetos tener un método Equals() con semántica más flexible. Por ejemplo, si tuviera mis druthers, Equivalente (1.00 m, 1.0 m) sería falso, pero Igual (1.00 m, 1.0 m) sería verdadero. Igual sería definido por la especificación como una propiedad transitoria, a diferencia de Equivalente que sería (siempre que se implemente correctamente) inmutable. – supercat

Cuestiones relacionadas