Khi nào thì dùng thử Try Cố định được sử dụng trong tên phương thức C #?


180

Chúng tôi đã thảo luận với đồng nghiệp về ý nghĩa của nó nếu tên phương thức bắt đầu bằng "Thử".

Có những ý kiến ​​sau:

  • Sử dụng "Thử" khi phương thức có thể trả về giá trị null.
  • Sử dụng "Thử" khi phương thức sẽ không đưa ra ngoại lệ.

Định nghĩa chính thức là gì? "Thử" nói gì trong tên phương thức? Có một số hướng dẫn chính thức về điều này?


83
+1 Những người đặt nhiều suy nghĩ này vào tên các chức năng của họ thực sự đang tìm kiếm "chàng trai tiếp theo". Không chắc tại sao điều này lại nhận được nhiều phiếu bầu (và điều đó đến từ một anh chàng đã bỏ rất nhiều trong số họ tối nay.)
Jonathon Reinhart

7
@JonathonReinhart, nó đã được bình chọn chặt chẽ vì "Vì hiện tại, câu hỏi này không phù hợp với định dạng Hỏi & Đáp của chúng tôi. Chúng tôi hy vọng câu trả lời sẽ được hỗ trợ bởi các sự kiện, tài liệu tham khảo hoặc chuyên môn cụ thể, nhưng câu hỏi này có thể sẽ gây ra tranh luận, tranh luận , bỏ phiếu hoặc thảo luận mở rộng. "
Pranav Hosangadi

16
một tuyên bố chính thức bởi Microsoft mà trả lời câu hỏi (xem câu trả lời của tôi). Làm thế nào mà không phải là một thực tế?
Erik Schierboom

6
@PranavHosangadi như Erik đã đề cập, nó được hỗ trợ bởi các sự kiện. Ngoài ra, có rất nhiều nhà phát triển C # rất có kinh nghiệm ở đây có chuyên môn cụ thể để cung cấp câu trả lời hợp lệ. Địa ngục, Eric Lippert là kiến ​​trúc sư ngôn ngữ C # chính. Tôi nghĩ rằng bạn có thể gọi đó là chuyên môn cụ thể .
Jonathon Reinhart

4
@ErikSchierboom Đó là hướng dẫn của MS là sự thật. Rằng hướng dẫn MS là hướng dẫn chính xác để sử dụng là chủ quan và gây tranh cãi.
Phục vụ

Câu trả lời:


148

Đây được gọi là mẫu TryPude và đã được Microsoft ghi lại. Các trường hợp ngoại lệ chính thức và hiệu suất trang MSDN nói :

Xem xét mẫu TryPude cho các thành viên có thể đưa ra các ngoại lệ trong các tình huống phổ biến để tránh các vấn đề về hiệu suất liên quan đến ngoại lệ.

Do đó, nếu bạn có mã mà trường hợp sử dụng thông thường có nghĩa là nó có thể đưa ra một ngoại lệ (chẳng hạn như phân tích cú pháp int), mẫu TryPude có ý nghĩa.


2
Một liên kết hữu ích mà tài liệu mô hình này (tìm kiếm TryParse) blogs.msdn.com/b/kcwalina/archive/2005/03/16/396787.aspx
Vivek Maharajh

2
Về cơ bản, nếu bạn có một phương thức TryPude, bạn nên có một phương thức Parse sẽ ném khi TryPude trả về false. Ngược lại, nếu bạn có phương thức Parse, bạn nên xem xét có phương thức
TryPude

5
+1. Chỉ cần thêm vào điều này, các trường hợp ngoại lệ thường dành cho các trường hợp "ngoại lệ". Nếu bạn đang làm điều gì đó có thể dễ dàng thất bại và thất bại đó không đáng chú ý, thì việc sử dụng mô hình này sẽ thành công hơn là thử / bắt
Adam Robinson

Có phải một mô hình như vậy thực sự đòi hỏi hướng dẫn từ Microsoft? Có vẻ những thứ khá cơ bản.
Dave Lawrence

19
Đó những thứ cơ bản, nhưng điều đó không có nghĩa là hướng dẫn không hữu ích. Làm cho các công cụ cơ bản trở nên khá khó khăn nếu bạn không biết rõ về nền tảng này.
Erik Schierboom

119

(Đã sửa) Có hướng dẫn chính thức, như Erik đề xuất.

Khi tôi thấy TrySomethingphương thức, tôi giả sử nó

  • không ném
  • trả lại bool
  • nếu tôi mong đợi giá trị, nó được trả về qua tham số 'out'
  • Somethingphương pháp tồn tại , cho phép tôi tự xử lý bất kỳ ngoại lệ nào. (chỉnh sửa, được đề xuất bởi Jesse Webb)

4
Sửa chữa - Nó có hướng dẫn chính thức. Xem câu trả lời của Erik.
nothrow

8
+1 Nhưng tôi cũng có một kỳ vọng thứ 4: Nếu có một TryFoophương thức, sẽ có một Foophương thức tương tự cho phép tôi tự xử lý bất kỳ ngoại lệ `` nào. Chữ ký của các phương thức này có thể sẽ khác nhau vì vậy cách sử dụng của chúng không thể thay thế cho nhau mà không có sự thay đổi mã khác.
Jesse Webb

1
@JlieWebb, cảm ơn bạn đã chỉ ra điều đó. Tôi đã thêm nhận xét của bạn vào câu trả lời của tôi, nếu bạn không phiền.
nothrow

1
"Không ném" dường như quá lớn. Ví dụ: Int32.TryPude (String, NumberStyles, IFormatProvider, Int32) ném ArgumentException nếu nó không thích tham số kiểu.
Jirka Hanika

Tôi đồng ý rằng "không ném" có thể được coi là quá mức, nhưng tôi tin rằng mục đích là truyền đạt rằng nó không ném như là kết quả của việc thực hiện chứ không phải là kết quả của giá trị của các tham số.
Bối rốiBoat

8

Tôi nghĩ bạn nên sử dụng trykhi bạn muốn tiến hành. Không có vấn đề gì khi một phương thức trả về một số giá trị hay không.

Trường hợp 1: nếu nó trả lại tiền phạt, bạn có thể tiến hành theo một cách nào đó.

Trường hợp 2: nếu nó không trở lại: nó vẫn ổn; bạn có thể tiến hành theo một số cách khác.

Và nếu bạn mong đợi một số giá trị là đầu ra của phương thức đó thì hãy sử dụng outtham số.

Thí dụ

int value
if (dictionary.TryGetValue("key", out value))
{
    // Proceed in some way
}
else
{
    // Proceed in some other way
}

6

Bạn phải sử dụng "Thử" trong tên phương thức, khi bạn muốn biểu thị thực tế rằng việc gọi phương thức có thể tạo ra kết quả không hợp lệ. Theo tiêu chuẩn .NET, nhân tiện, không phải là một hàm làm tăng ngoại lệ, mà là hàm trả về một số VALIDhoặc NON_VALID, từ quan điểm của chương trình, giá trị.

Cuối cùng, tất cả về quy ước đặt tên bạn quyết định sử dụng trong nhóm của bạn.


5

Đảm bảo bao gồm trytrong tên phương thức của bạn nếu:

  • bạn không ném bất kỳ ngoại lệ
  • phương pháp của bạn có chữ ký sau: bool TrySomething(input, out yourReturn)

Vì vậy, về cơ bản nếu chúng ta sử dụng try-method, chúng ta chỉ nhận được kết quả boolean.

Vì vậy, đoạn mã sau sẽ không đưa ra bất kỳ ngoại lệ nào:

string input = "blabla";
int number;
if (int.TryParse(input, out number))
{
// wooohooo we got an int!
} else
{
//dooh!
}

Trong khi đó mã này có thể (và trong trường hợp này sẽ) đưa ra các ngoại lệ:

string input = "blabla";
int number;
try
{
     number = int.Parse(input); //throws an exception
}
catch (Exception)
{
     //dooh!
}

Sử dụng các phương thức Thử là một cách an toàn hơn và phòng thủ hơn để viết mã. Ngoài ra đoạn mã số 2 cần nhiều hiệu năng hơn để thực thi nếu nó không phải là số nguyên.


Đoạn mã số 2 của bạn nên đọc int number = int.Parse(input);nếu bạn muốn nó có ý nghĩa hơn trong ngữ cảnh này.
Pierre Arnaud

@PierreArnaud Cảm ơn, đã thay đổi nó!
Fabian Bigler

Bạn vẫn còn thiếu phần int number;khai báo trước khối thử và number = ...bài tập.
Pierre Arnaud

@PierreArnaud Cảm ơn bạn, tôi cũng đã bao gồm 'int number'.
Fabian Bigler

Lưu ý rằng bạn vẫn có thể ném ngoại lệ nếu ngoại lệ có phần không liên quan đến hành động trực tiếp được thực hiện, như TryLoadFile(path, out file)woah, ra khỏi RAM. Vì vậy, người gọi sẽ không có lỗi đối với đường dẫn xấu hoặc quyền truy cập bị từ chối, nhưng ngoại lệ cho những điều không hợp lý cũng có thể xảy ra. Và tài liệu đó.
Luke Puplett

0

Chú Bob đưa ra ví dụ dưới đây trong cuốn sách Clean Code . Bất cứ khi nào chúng ta mong đợi một ngoại lệ được đưa ra, chúng ta có thể sử dụng Trytiền tố cho một tên phương thức:

public void sendShutDown()
{
    try{
        tryToShutDown();
    } catch (DeviceShutDownError e) {
        logger.log(e);            
    }
}

Và sau đó (thích nghi):

private void tryToShutDown()
{
    //some code with no error handling, but
    //something might go wrong here
}

Các tryToShutDownphương pháp không thực hiện bất kỳ xử lý lỗi, bởi vì đó là trách nhiệm của sendShutDownphương pháp.

Các TryParsemô hình của Microsoft vi phạm phương châm mã sạch sẽ mà nói rằng chúng ta nên tránh các thông số đầu ra.

Nếu chúng tôi không phát triển phiên bản C # mới, chúng tôi không phải tuân thủ tất cả các nguyên tắc của Microsoft. Đôi khi chúng không phải là tốt nhất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.