структура данных для хранения кортежа значения и единицы измерения (например, 7,0 миллиметров)
Звучит так, как будто у него есть семантика значения. Фреймворк предоставляет механизм для создания типов с семантикой значений, а именно struct
. Используйте это.
Практически все, что вы говорите в следующем параграфе вашего вопроса, как значения типа "за", так и "против", является вопросом оптимизации, основанным на том, как он будет взаимодействовать, для получения подробной информации о реализации среды выполнения. Поскольку в этом отношении есть как плюсы, так и минусы, явного победителя в эффективности нет. Поскольку вы не можете найти явного победителя по эффективности, даже не пытаясь это сделать, любая попытка оптимизации в этом отношении будет преждевременной. Как бы мне ни было надоело эта цитата о преждевременной оптимизации, когда кто-то пытается сделать что-то быстрее или меньше, она применима и здесь.
Одна вещь, которая не касается оптимизации:
Мне не нравится идея перегрузки == и! =, Если мой кортеж является классом, поскольку существует соглашение == и! = Is ReferenceEquals для ссылочных типов
Не совсем так. default заключается в том, что == и! = Имеют дело с равенством ссылок, но это так же, потому что это единственное значимое значение по умолчанию без дополнительных знаний о семантике класса. == и! = должны быть перегружены, когда это соответствует семантике классов, для этого необходимо использовать ReferenceEquals, когда единственное, что заботится о равенстве ссылок.
Если == и! = Перегружены, кто-то напишет if (myValue == null) и получит неприятное исключение времени выполнения, когда myValue в один прекрасный день окажется нулевым.
Только если перегрузка == имеет ошибку новичка. Нормальный подход был бы:
public static bool operator == (MyType x, MyType y)
{
if(ReferenceEquals(x, null))
return ReferenceEquls(y, null);
if(ReferenceEquals(y, null))
return false;
return x.Equals(y);
}
И, конечно, перегрузка Equals должна также проверять, что параметр имеет значение null, и возвращать false, если это так, для людей, вызывающих его напрямую. Это даже не оказывает существенного влияния на производительность по сравнению с поведением по умолчанию ==, когда одно или оба значения равны нулю, так в чем же проблема?
Еще один аспект заключается в том, что в C # нет ясного способа (в отличие, например, в C ++) различать ссылочные типы и типы значений при использовании кода, однако семантика сильно отличается.
Не совсем. Семантика по умолчанию в отношении равенства довольно различна, но, поскольку вы описываете что-то как намерение иметь семантику значения, это склоняется к тому, чтобы иметь это как тип значения, а не как тип класса. Кроме того, доступная семантика практически одинакова. Механизмы могут различаться в зависимости от бокса, совместного использования ссылок и т. Д., Но опять вернемся к оптимизации.
Может ли перегрузка в классе == /! = Быть оправдана при любых обстоятельствах?
Я бы скорее спросил, нельзя ли перегрузить == и! = Оправданно, когда это разумно сделать для класса?
Что касается того, что я, как программист, мог бы предположить о «UnitValue», я бы, вероятно, предположил, что это структура, так как она звучит так, как и должно быть. Но на самом деле, я бы даже не предположил, что, поскольку мне, в основном, будет все равно, пока я не сделаю что-то с этим, где это важно, учитывая, что это также звучит так, как будто оно должно быть неизменным, это сокращенный набор (семантические различия между изменяемым ссылочные типы и изменяемые структуры более эффективны на практике, но этот не вызывает затруднений).