Если вы будете поддерживать неявные преобразования только среди объектов ваших собственных типов, я бы посоветовал вам решить, какие «аксиомы» следует применять к таким преобразованиям (например, может быть полезно решить, что если a==b
, b==c
и a==c
все являются допустимыми, и два из них являются истинными, третий также должен быть истинным), а затем определить наиболее полезный набор преобразований, который позволил бы сохранить эти аксиомы. Я обсуждаю четыре полезные аксиомы в своем блоге на http://supercatnet.blogspot.com/2013/09/axioms-of-implicit-type-conversion.html (к сожалению, .NET Framework включает преобразования, которые нарушают все четыре, но запрещает преобразования, которые не должны были бы).
Важно учитывать, что неявные преобразования в неточных типов в большинстве случаев представляют меньший риск удивления, чем преобразования из неточных типов, но есть заметное исключение: если что-то более точного типа передается методу или оператору с перегрузками, которые принимают и более точный тип, и менее точный тип, в который оно может быть преобразовано, некоторый уровень «удивительного» поведения будет почти неизбежным если не сделать невозможным неявное преобразование [например, поведение, если программист пишет if (someLong == someFloat)
, может быть удивительным, но не потому, что потеря точности при неявном преобразовании long
в float
удивительна, а скорее потому, что существует по крайней мере шесть различных способов сравнения long
, а float
(*) и any , означающие, что компилятор может присоединиться к прямому сравнению, удивят тех, кто ожидал чего-то другого. Единственное решение, которое я знаю, чтобы избежать такого удивления, состоит в том, чтобы обеспечить перегрузки, чтобы явно охватить все неоднозначные случаи и пометить их тегом [Obsolete()]
. Делать это может быть несколько неловко, но это даст существенное преимущество в том, что сможет удовлетворить все четыре аксиомы.
(*) Программист мог бы, вероятно, намереваться проверить, было ли длинное значение равным значению числа с плавающей запятой, округленного до ближайшего, усеченного до нуля или обнуленного до отрицательной бесконечности; альтернативно, программист может захотеть проверить, был ли float
тот, который представляет long
, имеют ли float
и long
одинаковое номинальное значение или float
и long
оба преобразуются в одно и то же double
.