2009-07-17 28 views
10

nếu tôi chạy mã này # CTại sao Int32.TryParse đặt lại tham số ngoài khi không thể chuyển đổi?

int realInt = 3; 
string foo = "bar"; 
Int32.TryParse(foo, out realInt); 

Console.WriteLine(realInt); 
Console.Read(); 

tôi nhận được 0. Và tôi muốn biết tại sao! Bởi vì tôi không thể tìm ra lý do nào. Điều này buộc tôi phải tạo các biến tạm thời cho mọi phân tích cú pháp. Vì vậy xin! Các nhà lập trình vĩ đại của vũ trụ, khai sáng cho tôi!

+0

tôi định dạng mã cho bạn. Lần tới, nếu bạn không chắc chắn về cách định dạng nội dung nào đó trong trình chỉnh sửa MarkDown, hãy sử dụng thanh công cụ nhỏ phía trên vùng văn bản. Có một tùy chọn định dạng mã. – OregonGhost

+0

Cảm ơn sự giúp đỡ =) –

Trả lời

33

Đó là "hết", không phải "ref". Bên trong phương thức, để gán nó (không đọc nó trước) để thỏa mãn ý nghĩa của "out".

Trên thực tế, "out" là một ngôn ngữ mối quan tâm (không phải là một khuôn khổ một) - do đó, một C++ thực hiện quản lý có thể có thể bỏ qua điều này ... nhưng nó là phù hợp hơn để làm theo nó.

Thực tế; nếu phương thức trả về false bạn chỉ đơn giản là không nên nhìn vào giá trị; xử lý nó như rác cho đến khi nó được giao tiếp theo. Nó được cho là trả về 0, nhưng điều đó hiếm khi hữu ích.


Ngoài ra - nếu nó không làm điều này (tức là nếu nó giữ nguyên giá trị); những gì sẽ in này:

int i; 
int.TryParse("gibber", out i); 
Console.WriteLine(i); 

Đó là hoàn toàn hợp lệ C# ... vì vậy nó in gì?

+2

Giải thích tại sao * nó giống như thế này, để bạn có thể khẳng định rằng biến sẽ luôn luôn * được đặt trong bất kỳ mã nào sau lệnh gọi 'TryParse', ngay cả khi biến không được khởi tạo trước đó trong mã (do đó trình biên dịch không ném một lỗi khi bạn sử dụng biến sau lệnh gọi 'TryParse'; hãy thử làm tương tự với một hàm sử dụng từ khóa' ref'.) – Blixt

6

The Int32.TryParse Method (String, Int32) doc nói:

Chuyển đổi chuỗi đại diện của một số 32-bit số nguyên ký tương đương của nó. Giá trị trả lại cho biết liệu chuyển đổi có thành công hay không.

kết quả

Loại: System.Int32

Khi phương pháp này trở về, chứa 32-bit giá trị số nguyên ký tương đương với số chứa trong s, nếu chuyển đổi thành công, hay không nếu việc chuyển đổi không thành công. Việc chuyển đổi thất bại nếu tham số s là tham chiếu null (Không có gì trong Visual Basic), không phải là định dạng đúng, hoặc đại diện cho một số nhỏ hơn MinValue hoặc lớn hơn MaxValue. Tham số này được thông qua uninitialized.

+0

@Luke - look tại bit in đậm ... –

+0

@Marc: Đoạn thứ hai được thêm sau khi tôi đưa ra nhận xét. (Bình luận đã bị xóa ngay bây giờ.) – LukeH

0

Vì (ít nhất là trong C#), phương thức lấy một hoặc nhiều tham số phải đảm bảo rằng chúng ghi lại chúng. Bằng cách đó bạn không cần phải khởi tạo các trường cục bộ trong một phương thức trước khi chuyển chúng thành các tham số ngoài cho một phương thức.

0

tôi đoán là nó là một phần của C# spec:

10.5.1.3 thông số Output ... Trong vòng một phương pháp, giống như một biến địa phương, một tham số đầu ra ban đầu được coi> unassigned và phải được giao chắc chắn trước khi giá trị của nó được sử dụng.

Mọi tham số đầu ra của phương thức phải được gán rõ ràng trước khi phương thức trả về.

Nếu trường hợp này xảy ra, bạn không nên dựa vào giá trị kết quả.

0

Do tham số thứ hai là TryParse là tham số out, phương pháp TryParse buộc phải khởi tạo tham số. Đã có thông số được ref thay vì out bạn sẽ nhận được hành vi mong muốn của mình. Tuy nhiên, vì phương thức TryParse chỉ cần ouput một số và không nhận được bất kỳ số nào làm đầu vào out là lựa chọn thích hợp cho tham số.

2

Vì đây là cách hợp đồng 'thực hiện' hoạt động. Bất cứ khi nào bạn chuyển thông số out cho hàm, trách nhiệm của hàm đó là khởi tạo nó.

1

tài liệu MSDN cho Int32.TryParse khẳng định rằng nếu việc chuyển đổi không kết quả sẽ luôn luôn trở về 0.

Bạn thường phải hoặc sử dụng một biến kết quả tạm thời tức là

int value; 
bool succeeded = Int32.TryParse("astring", out value); 
if (succeeded) 
{ 
    // use value in some way 
} 

Hoặc bạn chỉ cần quấn phương thức đầy đủ trong câu lệnh if

int value; 
if (Int32.TryParse("astring", out value)) 
{ 
    // use value in some way 
} 

Cá nhân tôi thấy tùy chọn tốt hơn sau này.

4

Bởi vì tham số là một tham số ra bạn không cần phải khởi tạo realInt khi bạn khai báo nó, vì trình biên dịch có thể thấy rằng bạn đang đi qua nó để một phương pháp mà được guaranteeded để đặt nó vào một cái gì đó (vì của "ra").

Bây giờ, vì đây là tham số ngoài nên TryParse được yêu cầu để đặt nó thành thứ gì đó. Nó đặt nó là 0 vì đây là giá trị mặc định cho một int trong hầu hết các tình huống trong C#.

Bạn có thể viết nó như:

int realInt; 
string foo="bar"; 
if(int.TryParse(foo,out realInt)==false) 
{ 
    realInt=3; 
} 
+1

Cách tốt hơn để viết nó sẽ chỉ là để đặt một! toán tử ở đầu TryParse, ví dụ if (! Int32.TryParse (foo, out realInt)) – James

1
public static class IntHelper 
{ 
    public static bool TryParse(string s, ref int outValue) 
    { 
     int newValue; 
     bool ret = int.TryParse(s, out newValue); 
     if (ret) outValue = newValue; 
     return ret; 
    } 
} 
Các vấn đề liên quan