Trong nhiều bối cảnh trong đó một đối số phương thức hoặc toán tử không thuộc loại được yêu cầu, trình biên dịch C # sẽ cố gắng thực hiện chuyển đổi kiểu ẩn. Nếu trình biên dịch có thể làm cho tất cả các đối số thỏa mãn toán tử và phương thức của chúng bằng cách thêm các chuyển đổi ngầm định, nó sẽ làm như vậy mà không có khiếu nại, mặc dù trong một số trường hợp (đặc biệt là với các bài kiểm tra đẳng thức!), Kết quả có thể gây ngạc nhiên.
Hơn nữa, mỗi loại giá trị như inthoặc shortthực sự mô tả cả một loại giá trị và một loại đối tượng (*). Chuyển đổi ngầm định tồn tại để chuyển đổi giá trị sang các loại giá trị khác và để chuyển đổi bất kỳ loại giá trị nào sang loại đối tượng tương ứng, nhưng các loại đối tượng khác nhau không thể chuyển đổi lẫn nhau.
Nếu một người sử dụng == toán tử để so sánh a shortvà an int, thì shortnó sẽ được chuyển đổi hoàn toàn thành một int. Nếu giá trị số của nó là tương đương với các int, các intmà nó đã được chuyển đổi sẽ bằng intmà nó được so sánh. Tuy nhiên, nếu người ta cố gắng sử dụng Equalsphương thức ngắn để so sánh nó với một phương thức int, thì chuyển đổi ngầm định duy nhất đáp ứng quá tải của Equalsphương thức sẽ là chuyển đổi sang loại đối tượng tương ứng int. Khi shortđược hỏi liệu nó có khớp với đối tượng truyền vào hay không, nó sẽ quan sát rằng đối tượng trong câu hỏi là một intchứ không phải là một shortvà do đó kết luận rằng nó không thể bằng nhau.
Nói chung, mặc dù trình biên dịch sẽ không phàn nàn về nó, nhưng ta nên tránh so sánh những thứ không cùng loại; nếu một người quan tâm đến việc chuyển đổi mọi thứ sang một hình thức phổ biến sẽ cho kết quả tương tự, thì người ta nên thực hiện chuyển đổi đó một cách rõ ràng. Hãy xem xét, ví dụ,
int i = 16777217;
float f = 16777216.0f;
Console.WriteLine("{0}", i==f);
Có ba cách mà người ta có thể muốn so sánh intvới a float. Người ta có thể muốn biết:
- Liệu
floatgiá trị gần nhất có thể intphù hợp với float?
- Có phải toàn bộ phần số của
floatkhớp với int?
- Làm
intvà floatđại diện cho cùng một giá trị số.
Nếu một người cố gắng so sánh một intvà floattrực tiếp, mã được biên dịch sẽ trả lời câu hỏi đầu tiên; cho dù đó là những gì lập trình viên dự định, tuy nhiên, sẽ không rõ ràng. Thay đổi so sánh để (float)i == flàm rõ rằng ý nghĩa đầu tiên được dự định, hoặc(double)i == (double)f sẽ khiến mã trả lời câu hỏi thứ ba (và làm rõ nó là ý định gì).
(*) Ngay cả khi C # đặc tả coi một giá trị kiểu ví dụ System.Int32như là một đối tượng kiểu System.Int32, một cái nhìn như vậy là mâu thuẫn với yêu cầu rằng một mã chạy trên một nền tảng có liên quan giá trị và các đối tượng như sinh sống vũ trụ khác nhau spec. Hơn nữa, nếu Tlà một loại tham chiếu, và xlà một T, thì một tham chiếu của loại Tsẽ có thể tham chiếu x. Vì vậy, nếu một biến vloại và nội dung của nó thực sự là một .Int32 giữ một Object, tham chiếu kiểu Objectsẽ có thể giữ tham chiếu đến vhoặc nội dung của nó. Trong thực tế, một tham chiếu loại Objectsẽ có thể trỏ đến một đối tượng đang giữ dữ liệu được sao chép từ đóv , nhưng không phải cho vchính nó cũng như nội dung của nó. Điều đó sẽ gợi ý rằng khôngvObject