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ư int
hoặc short
thự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 short
và an int
, thì short
nó 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 int
mà nó đã được chuyển đổi sẽ bằng int
mà nó được so sánh. Tuy nhiên, nếu người ta cố gắng sử dụng Equals
phươ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 Equals
phươ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 int
chứ không phải là một short
và 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 int
với a float
. Người ta có thể muốn biết:
- Liệu
float
giá trị gần nhất có thể int
phù hợp với float
?
- Có phải toàn bộ phần số của
float
khớp với int
?
- Làm
int
và 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 int
và float
trự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 == f
là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.Int32
như 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 T
là một loại tham chiếu, và x
là một T
, thì một tham chiếu của loại T
sẽ có thể tham chiếu x
. Vì vậy, nếu một biến v
loại và nội dung của nó thực sự là một .Int32
giữ một Object
, tham chiếu kiểu Object
sẽ có thể giữ tham chiếu đến v
hoặc nội dung của nó. Trong thực tế, một tham chiếu loại Object
sẽ 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 v
chính nó cũng như nội dung của nó. Điều đó sẽ gợi ý rằng khôngv
Object