2009-04-15 25 views
16

Hiện tại tôi đang có nó với Guid s.Không thể chuyển đổi hoàn toàn loại 'X' thành 'chuỗi' - khi nào và cách nó quyết định rằng "không thể"?

Tôi chắc chắn nhớ rằng trong toàn bộ mã ở một số nơi, công cụ chuyển đổi tiềm ẩn này hoạt động, ở những nơi khác thì không. Cho đến bây giờ tôi không nhìn thấy mô hình.

Trình biên dịch quyết định khi nào nó không thể? Tôi có nghĩa là, phương pháp loại Guid.ToString() là hiện tại, không phải là nó được gọi là bất cứ khi nào chuyển đổi này là cần thiết?

Ai đó có thể vui lòng cho tôi biết trong hoàn cảnh nào việc chuyển đổi này được thực hiện tự động và khi tôi phải gọi myInstance.ToString() một cách rõ ràng?

+0

(đã thêm nhận xét trả lời câu hỏi của bạn) –

+0

Dùng thử và báo lỗi. Phep thử va lôi sai. – Will

Trả lời

32

Nói tóm lại, khi có một nhà điều hành chuyển đổi ngầm hay rõ ràng định nghĩa:

class WithImplicit { 
    public static implicit operator string(WithImplicit x) { 
     return x.ToString();} 
} 
class WithExplicit { 
    public static explicit operator string(WithExplicit x) { 
     return x.ToString(); } 
} 
class WithNone { } 

class Program { 
    static void Main() { 
     var imp = new WithImplicit(); 
     var exp = new WithExplicit(); 
     var none = new WithNone(); 
     string s1 = imp; 
     string s2 = (string)exp; 
     string s3 = none.ToString(); 
    } 
} 
+2

Chỉ cần tự tìm kiếm. Không thể tin rằng tôi đã bỏ lỡ điều này trong tất cả những năm này với C#. Tôi cho rằng không bao giờ cần nó thực sự ... Cảm ơn bạn đã làm cho tôi học một cái gì đó mới ngày hôm nay. – User

+0

Và tôi phải định nghĩa toán tử này ở đâu? Trong lớp Type tôi đoán? Tôi không thể thêm các phần mở rộng tĩnh vào các lớp WithImplicit và WithExplicit này. – User

+0

Không; không có điều gì như một toán tử mở rộng. –

4

Nơi duy nhất mà bạn có hiệu quả không cần phải gọi ToString() mình là khi concatenating chuỗi.

Guid g; 
int i; 
string s = "Hello "+g+' '+i; 

Sau đó, có một số trường hợp mà cuộc gọi được thực hiện bởi .NET Framework, chẳng hạn như trong String.Format().

Ngoài ra, trình biên dịch sẽ chỉ chuyển đổi một loại nếu nó được biết là tương thích (ví dụ: lớp cơ sở hoặc triển khai giao diện hoặc thông qua toán tử chuyển đổi được mã hóa rõ ràng). Khi bạn sử dụng một diễn viên và trình biên dịch biết rằng các loại không thể tương thích (ví dụ, không phải trong cùng một dòng thừa kế, và không phải là giao diện), nó cũng sẽ nói rằng nó không thể chuyển đổi nó. Cũng vậy với các thông số kiểu chung.

+0

Không chính xác; trình biên dịch cũng tôn trọng các toán tử chuyển đổi. Xem bài đăng của tôi để biết ví dụ về cả chuyển đổi ngầm định và rõ ràng, điều này làm * không * yêu cầu người gọi phải sử dụng liên kết ToString() hoặc chuỗi. –

+0

Bạn nói đúng về các toán tử chuyển đổi, nhưng tôi thường tránh chúng vì vậy tôi đã không đề cập đến chúng ở đây.Tôi sẽ thay đổi câu trả lời của tôi. – Lucero

4

Không, không có chuyển đổi tiềm ẩn từ GUID thành String, để không hoạt động ở bất kỳ đâu trong mã.

Chỉ hoạt động khi có chuyển đổi rõ ràng, nhưng chuyển đổi có thể không hiển thị. Ví dụ khi bạn nối dây:

string id = "--" + guidValue + " : " + num; 

này có thể trông giống như một chuyển đổi ngầm GUID-String, nhưng nó không phải là. Mã được tạo ra thực sự trông giống như sau:

string id = String.Concat(new object[] { "--", guidValue, " : ", num }); 

Tất cả toán hạng được đúc thành loại Object và được đặt trong một mảng. Phương pháp String.Concat sau đó gọi phương thức ToString cho mỗi mục trong mảng để lấy biểu diễn chuỗi cho chúng.

Các vấn đề liên quan