2010-10-05 5 views
10

Quiero una única clase genérica que pueda aceptar tipos de referencia o de valor, y solo realizar una acción basada en una prueba de igualdad. considere lo siguiente:Restricciones genéricas: ¿Puedo probar Igualdad de genérico que puede ser un tipo de referencia o de valor?

public class Property<TProp> 
    where TProp : struct, IEquatable<TProp> 
{ 
    public TProp Value; 

    public void SetValue(ObservableObject owner, TProp value) 
    { 
     if (!Value.Equals(value))  // cannot use != on struct constrained TProp 
     { 
      // ... set the property 
     } 
    } 
} 

public class ByRefProperty<TProp> 
    where TProp : class // Dont want to require IEquatable<> on reference type TProp 
{ 
    public TProp Value; 

    public void SetValue(ObservableObject owner, TProp value) 
    { 
     if (Value != value)   
     { 
      // ... set the property 
     } 
    } 
} 

estoy tener que utilizar restricciones genéricas y dos clases de poder probar valor del tipo de la igualdad frente a la igualdad tipo de referencia. ¿Hay alguna forma de evitar esto para que termine con solo una clase?

No quiero particularmente una solución que implique tipos de valores de boxeo, usando reflexión, o generación de IL en tiempo de ejecución. ¿Hay alguna solución simple que me haya perdido aquí?

Respuesta

15

La mejor manera de hacer que esto es generalmente EqualityComparer<T>.Default:

public void SetValue(ObservableObject owner, TProp value) 
{ 
    if (!EqualityComparer<TProp>.Default.Equals(Value, value)) 
    { 
     // ... set the property 
    } 
} 

Tenga en cuenta que esto incluso trata los valores nulos para usted en el camino lógico (nulo es igual a null, pero nada más).

+0

¿Utilizará esto una lógica de Igualdad personalizada definida en la implementación de 'IEquatable '? –

+1

@Justin, sí, si el tipo lo implementa. –

+0

@Jon - Aprende algo nuevo todos los días ... otra vez. –

Cuestiones relacionadas