2010-12-30 18 views
17

Ví dụ này là trong C# nhưng tôi hy vọng có thể áp dụng cho những người khác cũng dễ dàng.Bất kỳ sự cố nào khai báo biến và sử dụng TryParse để khởi tạo biến đó trên cùng một dòng?

Gần đây tôi phát hiện ra rằng những điều sau đây dường như chỉ làm việc tốt:

int i = Int32.TryParse(SomeString, out i) ? i : -1; 

Bằng cách nào đó nó có vẻ như thể biến i không nên về mặt kỹ thuật có thể truy cập tại điểm nó xuất hiện trong TryParse. Hoặc tôi có thể chính xác để giả định rằng int i tuyên bố biến hiệu quả, mặc dù chưa có kết thúc câu lệnh?

+0

Ha!Điều đó thật tuyệt. Mã này là không tốt nếu -1 là một giá trị hợp lệ của SomeString, nhưng vẫn còn. Tôi thường muốn tôi có thể tuyên bố một biến "out" một cách ngầm định, ví dụ: nó sẽ không được tốt đẹp nếu bạn có thể viết 'if (int.TryParse (s, ra var i)) {...}' trong đó 'i' là một biến mới chưa bao giờ được khai báo trước đây? – Qwertie

+0

Có lẽ, như Henk gợi ý, một phương pháp trợ giúp là tốt nhất. ví dụ, 'int CustomIntParse (chuỗi s, int mặc định) {}' – JYelton

+0

Tôi đã chụp một số phương pháp trợ giúp để xem xét. –

Trả lời

10

int i tuyên bố biến và sử dụng biến trong thông số out khởi chạy biến đó. Vì vị từ phải được đánh giá trước hậu quả, do đó, i do đó được khai báo và khởi tạo trước khi sử dụng. (out thông số phải được chỉ định trước khi trở về, do đó, nó chắc chắn là khởi tạo trong mọi trường hợp.)

Điều đó nói rằng, có đồng nghiệp của tôi sẽ ném một phù hợp nhìn thấy một cái gì đó như thế trên cơ sở phong cách. :-)

EDIT: Sau khi khảo sát cách điều này đã bị lung lay, tôi sẽ đề xuất một vài phương pháp trợ giúp thay thế có thể có. Đặt tên cho lớp tĩnh hoạt động như tài liệu hướng dẫn cho các phương thức trợ giúp ở đây.

internal static class TryConvert 
{ 
    /// <summary> 
    /// Returns the integer result of parsing a string, or null. 
    /// </summary> 
    internal static int? ToNullableInt32(string toParse) 
    { 
     int result; 
     if (Int32.TryParse(toParse, out result)) return result; 
     return null; 
    } 

    /// <summary> 
    /// Returns the integer result of parsing a string, 
    /// or the supplied failure value if the parse fails. 
    /// </summary> 
    internal static int ToInt32(string toParse, int toReturnOnFailure) 
    { 
     // The nullable-result method sets up for a coalesce operator. 
     return ToNullableInt32(toParse) ?? toReturnOnFailure; 
    } 
} 

internal static class CallingCode 
{ 
    internal static void Example(string someString) 
    { 
     // Name your poison. :-) 
     int i = TryConvert.ToInt32(someString, -1); 
     int j = TryConvert.ToNullableInt32(someString) ?? -1; 

     // This avoids the issue of a sentinel value. 
     int? k = TryConvert.ToNullableInt32(someString); 
     if (k.HasValue) 
     { 
      // do something 
     } 
    } 
} 
+0

Đó là lý do tại sao tôi đặt ra câu hỏi. Tôi luôn tìm cách đơn giản hóa mã (ít nhất là đến mức nó vẫn có thể đọc được). Tôi cảm thấy tuyên bố này là có thể đọc được, nhưng bạn có thể xây dựng các cân nhắc về phong cách? – JYelton

+0

@JYelton Một số người tìm thấy các toán tử bậc ba ít có thể đọc được cho người mới bắt đầu. Sau đó, có một thực tế là có việc sử dụng các tác dụng phụ của tham số ra để khởi tạo i trước khi phân nhánh nhánh. Nếu bạn phải đặt một câu hỏi về SO cho dù có bất kỳ vấn đề làm điều này, bạn đã trả lời câu hỏi dễ đọc của bạn. :) –

+0

Tôi là một trong những người sẽ thích hợp với phong cách. Trong khi nó hoạt động, có vẻ khó hiểu. Nó không phải là ngay lập tức rõ ràng những gì đang xảy ra, vì vậy tôi phải chơi trình biên dịch để con số nó ra. –

4

Gần đây tôi phát hiện ra rằng sau dường như chỉ làm việc tốt

int i = Int32.TryParse(SomeString, out i) ? i : -1; 

Nó hoạt động, nhưng nó không phải là tốt.

Bất kỳ vấn đề nào tuyên bố biến và sử dụng TryParse để khởi tạo biến đó trên cùng một dòng?

Có, dễ đọc. Tôi nghĩ rằng điều này có vẻ khủng khiếp, và nó đang làm việc gấp đôi.


Một phần vấn đề của bạn là bạn muốn -1 làm mặc định. Int32.TryParse xác định rõ ràng 0 làm giá trị ngoài khi chuyển đổi không thành công.

Tôi vẫn sẽ chia nhỏ trong 2 dòng vì mục đích dễ đọc.

int i; 
if (! int.TryParse(SomeString, out i)) i = -1; 

Và khi bạn cần điều này rất nhiều, viết một phương thức helper (tĩnh nhưng không mở rộng):

int i = Utils.ParseInt(SomeString, -1); 
+0

Bạn có thể chia nhỏ thành các dòng mã riêng biệt không? Hoặc là có một cách súc tích để đặt một int vào một giá trị phân tích cú pháp của một chuỗi, và chỉ định một giá trị mặc định cho phân tích cú pháp thất bại? – JYelton

+0

JYelton: câu hỏi công bằng, TryParse là xấu xí. Tôi sẽ chỉnh sửa. –

+0

Tôi thích phương thức trợ giúp tĩnh. Làm cho nó rõ ràng những gì đang xảy ra. –

4

Hãy nhớ rằng không có hành ternary trong CIL.

int i = Int32.TryParse(SomeString, out i) ? i : -1; 

Mã của bạn được chuyển thành CIL đại diện cho mã C# sau:

int i; 
if (Int32.TryParse(SomeString, out i)) 
    i = i; 
else 
    i = -1; 

Đó là hoàn toàn tốt đẹp.

+0

Điều này làm cho nó rõ ràng hơn rằng nếu tôi nhấn mạnh vào việc giữ cấu trúc này, ít nhất tôi nên đảo ngược câu lệnh if để 'i' chỉ được đặt khi thất bại (được hiển thị trong ví dụ của Henk). Cảm ơn. – JYelton

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