Общие ограничения: Могу ли я проверить равенство общего, которое может быть ссылкой или типом значения? - PullRequest
10 голосов
/ 05 октября 2010

Мне нужен один универсальный класс, который может принимать ссылочный тип или тип значения и выполнять только действие, основанное на тесте на равенство учитывать следующее:

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

Мне нужно использовать общие ограничения и два класса, чтобы иметь возможность проверить равенство типов значений и равенство ссылочных типов. Есть ли способ обойти это так, чтобы я закончил только один класс?

Мне особо не нужно решение, которое включает в себя типы значений бокса, с использованием отражения или генерации IL во время выполнения. Есть ли простое решение, которое я здесь упустил?

1 Ответ

15 голосов
/ 05 октября 2010

Лучший способ сделать это, как правило, EqualityComparer<T>.Default:

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

Обратите внимание, что это даже обрабатывает нулевые значения для вас логическим способом (ноль равно нулю, нобольше ничего).

...