Dưới đây là một đăng từ following article:
Sự khác biệt giữa ép buộc và đúc thường bị bỏ qua. Tôi có thể thấy tại sao; nhiều ngôn ngữ có cú pháp và thuật ngữ giống nhau (hoặc tương tự) cho cả hai thao tác. Một số ngôn ngữ thậm chí có thể đề cập đến bất kỳ chuyển đổi nào là "truyền", nhưng giải thích sau đây đề cập đến các khái niệm trong CTS.
Nếu bạn đang cố gán giá trị của một loại nào đó cho một vị trí thuộc một loại khác, bạn có thể tạo ra một giá trị của loại mới có ý nghĩa tương tự với bản gốc. Đây là sự ép buộc. Coercion cho phép bạn sử dụng kiểu mới bằng cách tạo một giá trị mới theo cách nào đó giống với bản gốc. Một số coercions có thể loại bỏ dữ liệu (ví dụ: chuyển đổi int 0x12345678 thành 0x5678 ngắn), trong khi một số khác có thể không (ví dụ: chuyển đổi int 0x00000008 thành 0x0008 ngắn hoặc 0x0000000000000008 dài).
Nhớ lại rằng các giá trị có thể có nhiều loại. Nếu tình huống của bạn hơi khác và bạn chỉ muốn chọn một loại khác của các loại giá trị, việc truyền là công cụ cho công việc. Truyền đơn giản chỉ ra rằng bạn muốn vận hành trên một kiểu cụ thể mà một giá trị bao gồm.
Sự khác biệt ở cấp mã thay đổi từ C# đến IL. Trong C#, cả đúc và ép buộc trông khá tương tự:
static void ChangeTypes(int number, System.IO.Stream stream)
{
long longNumber = number;
short shortNumber = (short)number;
IDisposable disposableStream = stream;
System.IO.FileStream fileStream = (System.IO.FileStream)stream;
}
Ở cấp độ IL chúng hoàn toàn khác:
ldarg.0
conv.i8
stloc.0
ldarg.0
conv.i2
stloc.1
ldarg.1
stloc.2
ldarg.1
castclass [mscorlib]System.IO.FileStream
stloc.3
Đối với mức độ hợp lý, có một số khác biệt quan trọng. Điều quan trọng nhất cần nhớ là việc ép buộc tạo ra một giá trị mới, trong khi quá trình truyền thì không. Danh tính của giá trị ban đầu và giá trị sau khi truyền đều giống nhau, trong khi danh tính của giá trị bị ép buộc khác với giá trị ban đầu; coersion tạo ra một cá thể mới, khác biệt, trong khi đúc thì không. Một hệ quả là kết quả của việc đúc và bản gốc sẽ luôn luôn là tương đương (cả về bản sắc và bình đẳng), nhưng giá trị bị ép buộc có thể hoặc không thể bằng với bản gốc, và không bao giờ chia sẻ bản sắc gốc.
Thật dễ dàng để xem các tác động của cưỡng chế trong các ví dụ ở trên, vì các loại số luôn được sao chép theo giá trị. Mọi thứ trở nên phức tạp hơn một chút khi bạn làm việc với các loại tham chiếu.
class Name : Tuple<string, string>
{
public Name(string first, string last)
: base(first, last)
{
}
public static implicit operator string[](Name name)
{
return new string[] { name.Item1, name.Item2 };
}
}
Trong ví dụ dưới đây, một chuyển đổi là một diễn viên, trong khi chuyển đổi khác là một sự ép buộc.
Tuple<string, string> tuple = name;
string[] strings = name;
Sau khi chuyển đổi này, tên và tên bằng nhau, nhưng các chuỗi không bằng một trong hai. Bạn có thể làm cho tình huống tốt hơn một chút (hoặc hơi khó hiểu hơn) bằng cách thực hiện Equals() và toán tử ==() trên lớp Name để so sánh một Name và một chuỗi [].Những toán tử này sẽ “sửa” vấn đề so sánh, nhưng bạn vẫn sẽ có hai trường hợp riêng biệt; bất kỳ sửa đổi nào đối với các chuỗi sẽ không được phản ánh trong tên hoặc bộ, trong khi các thay đổi đối với một trong hai tên hoặc tuple sẽ được phản ánh trong tên và bộ, nhưng không được ghi trong chuỗi. Mặc dù ví dụ trên có nghĩa là minh họa một số khác biệt giữa việc ép và ép buộc, nó cũng là một ví dụ tuyệt vời về lý do bạn nên thận trọng khi sử dụng toán tử chuyển đổi với các kiểu tham chiếu trong C#.
Điều gì về [bài viết trên Wikipedia] (http://en.wikipedia.org/wiki/Type_conversion)? –