Во многих контекстах, где аргумент метода или оператора не относится к требуемому типу, компилятор C # попытается выполнить неявное преобразование типа. Если компилятор может заставить все аргументы удовлетворять свои операторы и методы, добавляя неявные преобразования, он сделает это без жалоб, даже если в некоторых случаях (особенно с тестами на равенство!) Результаты могут быть неожиданными.
Кроме того, каждый тип значения, такой как intили shortфактически, описывает как вид значения, так и вид объекта (*). Неявные преобразования существуют для преобразования значений в другие типы значений и преобразования любого значения в соответствующий ему вид объекта, но различные типы объектов не могут быть неявно преобразованы друг в друга.
Если использовать ==оператор для сравнения a shortи an int, shortбудет неявно преобразован в int. Если его числовое значение было равно значению, то значение int, в intкоторое оно было преобразовано, будет равно значению, intс которым оно сравнивается. Однако, если кто-то попытается использовать Equalsметод на коротком отрезке, чтобы сравнить его с объектом int, единственным неявным преобразованием, которое удовлетворяет перегрузке Equalsметода, будет преобразование в тип объекта, соответствующий int. Когда его shortспросят, соответствует ли он переданному объекту, он заметит, что рассматриваемый объект является, intа неshort и, таким образом выводу, что он не может быть равен.
В общем, хотя компилятор не будет жаловаться на это, следует избегать сравнения вещей, которые не относятся к одному типу; если кто-то интересуется, приведет ли преобразование вещей к общей форме к тому же результату, следует выполнить такое преобразование явно. Рассмотрим, например,
int i = 16777217;
float f = 16777216.0f;
Console.WriteLine("{0}", i==f);
Есть три способа сравнить a intс a float. Возможно, вы захотите узнать:
- Есть ли наиболее возможное
floatзначение к intсопрягать float?
- Имеет ли весь номер частью
floatсопрягать int?
- Сделайте
intи floatпредставляют одно и то же числовое значение.
Если попытаться сравнить intи floatнапрямую, скомпилированный код ответит на первый вопрос; Однако далеко не очевидно, что задумал программист. Изменение сравнения на (float)i == fпрояснит, что было предназначено первое значение, или (double)i == (double)fзаставит код ответить на третий вопрос (и прояснить, что было задумано).
(*) Даже если спецификация C # рассматривает значение типа, например, System.Int32как объект типа System.Int32, такое представление противоречит требованию, чтобы код выполнялся на платформе, спецификация которой рассматривает значения и объекты как населяющие разные вселенные. Кроме того, если Tэто ссылочный тип, а x- это T, то ссылка типа Tдолжна иметь возможность ссылаться на x. Таким образом, если переменная vтипа Int32содержит Object, ссылка типа Objectдолжна иметь возможность содержать ссылку vили ее содержимое. Фактически, ссылка типа Objectможет указывать на объект, содержащий скопированные данные, и его содержимое на самом деле не является .v , но не на vсебя или его содержимое. Это предполагает, что ниvObject