2010-10-05 7 views
10

Chcę, aby pojedyncza klasa generyczna mogła akceptować typy referencyjne lub wartościowe i wykonywać tylko działanie oparte na teście równości. rozważyć następujące kwestie:Ogólne ograniczenia: Czy mogę przetestować równość generycznego, który może być typem odniesienia lub wartością?

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 
     } 
    } 
} 

mam użyć generycznych ograniczenia i dwie klasy, aby móc przetestować typ wartości równości vs równości typu odniesienia. Czy jest jakiś sposób obejścia tego, że skończę z jedną klasą?

Nie chcę szczególnie rozwiązania, które obejmuje typy wartości bokserskich, użycie odbicia lub generowanie IL w czasie wykonywania. Czy istnieje proste rozwiązanie, którego tu nie mam?

Odpowiedz

15

Najlepszym sposobem, aby to zrobić jest na ogół EqualityComparer<T>.Default:

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

Zauważ, że nawet ten obsługuje wartości null dla Ciebie w logiczny sposób (null jest równa null, ale nic innego).

+0

Czy użyje to dowolnej niestandardowej logiki równającej zdefiniowanej w implementacji 'IEquatable '? –

+1

@Justin, tak to robi, jeśli typ go implementuje. –

+0

@Jon - Dowiedz się czegoś nowego każdego dnia ... jeszcze raz. –

Powiązane problemy