2015-07-31 19 views
8

Mục đích của việc sử dụng String.Concat(Object) thay vì String.Concat(String) trong C# là gì? Tại sao không sử dụng cuộc gọi ngầm của Object.ToString() thay vì tự mình chuyển một số object cũng có thể gây ra sự cố xảy ra?Mục đích của String.Concat (Object) thay vì String.Concat (String)

Int32 i = 5; 
String s = "i = "; 

// Boxing happens, ToString() is called inside 
Console.WriteLine(s + i); 
// Why compiler doesn't call ToString() implicitly? 
Console.WriteLine(s + i.ToString()); 

Cung cấp cho chúng tôi IL sau.

.method private hidebysig static void MyDemo() cil managed 
{ 
    // Code size  47 (0x2f) 
    .maxstack 2 
    .locals init ([0] int32 i, [1] string s) 
    IL_0000: nop 
    IL_0001: ldc.i4.5 
    IL_0002: stloc.0 
    IL_0003: ldstr  "i = " 
    IL_0008: stloc.1 
    IL_0009: ldloc.1 
    IL_000a: ldloc.0 
    IL_000b: box  [mscorlib]System.Int32 
    IL_0010: call  string [mscorlib]System.String::Concat(object, object) 
    IL_0015: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_001a: nop 
    IL_001b: ldloc.1 
    IL_001c: ldloca.s i 
    IL_001e: call  instance string [mscorlib]System.Int32::ToString() 
    IL_0023: call  string [mscorlib]System.String::Concat(string, string) 
    IL_0028: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_002d: nop 
    IL_002e: ret 
} // end of method Program::MyDemo 
+0

Câu hỏi hay. Tôi muốn thêm vào đây: tại sao không có phương thức 'string Concat (string s, T value)', sẽ được sử dụng bởi toán tử '+'. – Dennis

+0

@ Dennis điều gì sẽ là việc sử dụng điều đó? –

+0

@Dennis Trình biên dịch sẽ kết nối 'giá trị T' bằng' chuỗi s' như thế nào? Có thể ghép nối bất kỳ 'T' nào không? –

Trả lời

3

Tại sao trình biên dịch nên thực hiện điều đó? Nó không thể.

Nếu bạn vượt qua trong một đối tượng (trong trường hợp này là đóng hộp int), khả năng duy nhất cho trình biên dịch là gọi string.Concat(object, object). Nó không thể gọi string.Concat(string, string) vì không phải cả hai tham số đều là string và do đó tuân thủ quá tải thứ hai.

Thay vào đó, nó gọi string.Concat(object, object) và thực hiện ToString bên trong nếu có.

Bạn là nhà phát triển có kiến ​​thức thân mật về cách thức hoạt động của phương pháp string.Concat. Trình biên dịch không biết rằng cuối cùng tất cả sẽ trở thành một string.

Ngoài ra, điều gì sẽ xảy ra nếu một trong số object s là null? ToString sẽ không thành công với ngoại lệ. Điều này không có ý nghĩa. Chỉ cần vượt qua trong số object và để mã xử lý nó.

+1

Trình biên dịch không biết rằng tất cả các loại kế thừa Object cuối cùng. Đối tượng chứa phương thức ToString(). Vì vậy, khi trình biên dịch đáp ứng không phải là một đối số String của một hàm mong đợi String nó có thể ngầm gọi ToString(). –

+1

Nhưng bạn là một nhà phát triển có kiến ​​thức thân mật về cách thức hoạt động của phương thức 'string.Concat'. Trình biên dịch không biết rằng cuối cùng nó trở thành một 'chuỗi'. –

+2

@JohnDoe - đường phân chia ở đâu? Bạn có nói rằng, đối với * bất kỳ tập quá tải nào xảy ra ở hai trạng thái quá tải, trong đó người ta chấp nhận tham số 'string' trong cùng một vị trí mà tham số khác chấp nhận tham số' object', nó luôn gọi là 'ToString()' trên đối tượng, và do đó quá tải 'đối tượng' không bao giờ được gọi? –

0

tham khảo Nguồn: http://referencesource.microsoft.com/#mscorlib/system/string.cs,8281103e6f23cb5c

tiết lộ rằng:

public static String Concat(Object arg0) { 
     Contract.Ensures(Contract.Result<String>() != null); 
     Contract.EndContractBlock(); 

     if (arg0 == null) 
     { 
      return String.Empty; 
     } 
     return arg0.ToString(); 
    } 

Nó chỉ đơn giản là tạo ra một chuỗi đại diện của đối tượng đó. Vì vậy, bất kỳ đối tượng nào bạn vượt qua được chuyển đổi thành String. String.Empty nếu nó không có giá trị. Tôi nghĩ rằng điều này cũng giúp chúng tôi kiểm tra đối tượng "rỗng" trước khi chuyển đổi thành string.

+1

Khá thú vị rằng có một phương pháp để concat _a duy nhất thing_. – IllidanS4

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