Во многих контекстах, где аргумент метода или оператора не относится к требуемому типу, компилятор 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
себя или его содержимое. Это предполагает, что ниv
Object