Come confrontare due elementi dello stesso tipo generico ma non vincolato per l'uguaglianza? [duplicare]

StackOverflow https://stackoverflow.com/questions/336884

Domanda

  

Possibile duplicato:
   Può & # 8217; t operator == essere applicato a tipi generici in C #?

Ho la seguente classe generica e il compilatore si lamenta che " Operator '!=' cannot be applied to operands of type 'TValue' and 'TValue' " (vedi CS0019 ):

public class Example<TValue>
{
    private TValue _value;
    public TValue Value
    {
        get { return _value; }
        set
        {
            if (_value != value) // <<-- ERROR
            {
                _value= value;
                OnPropertyChanged("Value");
            }
        }
    }
}

Se vincolo TValue a class, potrei usare Object.Equals(). Dato che ne ho bisogno per entrambe le strutture e le classi, sarei molto felice se potessi evitarlo.

Quindi la domanda è: come posso confrontare due elementi dello stesso tipo generico non vincolato per l'uguaglianza?

È stato utile?

Soluzione

Hai provato qualcosa del genere?

public class Example<TValue>
{
    private TValue _value;
    public TValue Value
    {
        get { return _value; }
        set
        {

            if (!object.Equals(_value, value))
            {
                _value = value;
                OnPropertyChanged("Value");
            }
        }
    }
}

Altri suggerimenti

Tre opzioni:

  • Vincola TValue per implementare IEquatable<TValue> e quindi chiama x.Equals(y)
  • Prendi un altro parametro di tipo IEqualityComparer<TValue> e usalo
  • Utilizzare EqualityComparer<TValue>.Default per eseguire i confronti

Puoi sempre mescolare e abbinare le opzioni 2 e 3, ovviamente - default al comparatore predefinito, ma consenti anche di fornirne uno specifico.

  • Equals () per i tipi di valore
  • ReferenceEquals () per i tipi di riferimento

IComparable è un'opzione?

public class Example<TValue> where TValue: IComparable
{
    private TValue _value;
    public TValue Value
    {
        get { return _value; }
        set
        {

            if (_value.CompareTo(value) != 0)
            {
                _value = value;
                OnPropertyChanged("Value");
            }
        }
    }
}

Penso che l'operatore != non possa essere applicato qui perché ci sono casi in cui non può essere utilizzato. Ad esempio, == non può essere utilizzato per confrontare le strutture, a meno che gli operatori di confronto (int != int <=>) non siano sovraccarichi.

Ovviamente, puoi confrontare le strutture linguistiche, come <=>, ma non sono sicuro di come sia implementato.

Quindi, poiché TValue può essere una struttura personalizzata , non può utilizzare l'operatore <=>.

public static bool operator ==(EntityBase<T> entity1, EntityBase<T> entity2)
        {
            if ((object)entity1 == null && (object)entity2 == null)
            {
                return true;
            }

            if ((object)entity1 == null || (object)entity2 == null)
            {
                return false;
            }

            if (Comparer<T>.Default.Compare(entity1.Id, entity2.Id) != 0)
            {
                return false;
            }

            return true;
        }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top