2010-03-15 18 views
5

Giả sử một phương pháp với chữ ký sauHành vi tiêu chuẩn cho tham số ngoài khi phương thức TryXxxx trả về false là gì?

bool TryXxxx(object something, out int toReturn) 

nó là gì có thể chấp nhận cho toReturn là nếu TryXxxx lợi nhuận sai?

Ở chỗ nó được phỏng đoán rằng không nên sử dụng toReturn nếu TryXxxx không thành công?

Nếu toReturn là loại có thể lưu trữ, thì sẽ có ý nghĩa để trả về giá trị rỗng. Nhưng int không phải là vô giá trị và tôi không muốn phải ép buộc.

Nếu toReturn luôn là giá trị nhất định nếu TryXxxx không thành công, chúng tôi có nguy cơ có vị trí mà 2 giá trị có thể được xem xét để cho biết điều tương tự. Tôi có thể thấy điều này dẫn đến sự nhầm lẫn tiềm năng có thể xảy ra nếu giá trị 'mặc định' được trả về dưới dạng phản hồi hợp lệ (khi TryXxxx trả về true).

Từ điểm triển khai nếu chế độ xem có vẻ như có toReturn là giá trị [ny] là dễ nhất, nhưng có điều gì quan trọng hơn để xem xét không?

Trả lời

6

Tôi sẽ rõ ràng làm tài liệu như sử dụng giá trị mặc định cho loại (bất kể loại đó là gì; vì vậy 0 trong trường hợp này nhưng default(T) trong trường hợp tổng quát hơn). Có nhiều trường hợp khác nhau mà giá trị mặc định là chính xác những gì bạn muốn nếu giá trị không xuất hiện - và trong trường hợp đó bạn chỉ có thể bỏ qua giá trị trả về từ phương thức.

Lưu ý rằng đây là phương pháp như int.TryParseDictionary.TryGetValue làm.

+0

Và bên cạnh đó, nếu bạn quan tâm đến kết quả đủ mà bạn không muốn sử dụng mặc định, trừ khi đó rõ ràng là giá trị là XYZ (được phân tích cú pháp, v.v.), sau đó bạn thực sự cần phải kiểm tra giá trị trả về từ phương thức. –

+0

Đã không nghĩ về người tiêu dùng có lý do để sử dụng giá trị trả lại nếu Thử trả về false. –

4

Nó có thể là default(int):

bool TryXxxx(object something, out int toReturn) 
{ 
    toReturn = default(int); 
    return false; 
} 
2

tôi sẽ nói default, nhưng thực sự nó không phải vấn đề. Quy ước với TryX là người gọi nên kiểm tra giá trị trả về và chỉ sử dụng tham số ngoài khi phương thức trả về true.

2

Về cơ bản, đó là điều gì đó. Tôi sẽ ghi lại nó là "không được định nghĩa". giá trị hợp lý là:

  • mặc định()
  • MINVALUE, MaxCValue, NEWVALUE (như int mới()), null
  • giá trị NAN (Double.NaN)

Nhưng nói chung, Tôi woul thực sự nói "không được xác định" và không cung cấp cho mọi người một cái gì đó họ có thể cố gắng dựa vào.

+0

Về mặt lý thuyết, bạn có thể ghi lại phương thức là đưa ra hành vi "không xác định", nhưng trên thực tế bạn cần cung cấp triển khai cụ thể. Có, bạn có thể trả về một giá trị ngẫu nhiên, có thể kích hoạt các lỗi không hoạt động bề mặt, nhưng một giải pháp thực tế thường trả về giá trị mặc định, mặc định, do đó "mặc định (T)" có lẽ là giá trị tốt nhất. Cũng lưu ý rằng trong trường hợp này, bạn vẫn có thể viết tài liệu cho phương thức như là đưa ra hành vi không xác định, cho phép bạn tùy chọn thay đổi giá trị sau này, nếu cần. Tuy nhiên, tôi có thể trả về bản thân mặc định. –

0

1) Thực tế, tôi cho rằng không nên quan trọng vì bạn nên luôn luôn kiểm tra kết quả boolean của các phương pháp đó trước khi xử lý giá trị. Đó là những gì các phương pháp TryXXX dành cho.

2) Tuy nhiên, trong những trường hợp như vậy, tôi luôn tham khảo triển khai trong khuôn khổ .NET để đảm bảo tính nhất quán.Và một cái nhìn nhanh chóng vào Reflector cho thấy kiểu Int32 trả về 0 nếu phân tích thất bại:

internal static unsafe bool TryParseInt32(string s, NumberStyles style, NumberFormatInfo info, out int result) 
{ 
    byte* stackBuffer = stackalloc byte[1 * 0x72]; 
    NumberBuffer number = new NumberBuffer(stackBuffer); 
    result = 0; // <== see here! 
    if (!TryStringToNumber(s, style, ref number, info, false)) 
    { 
     return false; 
    } 
    if ((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None) 
    { 
     if (!HexNumberToInt32(ref number, ref result)) 
     { 
      return false; 
     } 
    } 
    else if (!NumberToInt32(ref number, ref result)) 
    { 
     return false; 
    } 
    return true; 
} 

Tuy nhiên, không biết các chi tiết thực hiện, nó vẫn có thể xảy ra rằng vấn đề phân tích xảy ra khi một giá trị đã được gán (một phần). Trong trường hợp này, giá trị có thể không còn là 0. Vì vậy, bạn nên luôn luôn dính vào "giải pháp" 1)! :-)

gehho.

0

Trước khi .net, mẫu bình thường là dành cho các phương thức TryXX đơn giản là để nguyên đối số được truyền theo tham chiếu chưa được sửa đổi. Đây là một mô hình rất hữu ích, vì nó có nghĩa là mã mà muốn sử dụng một giá trị mặc định có thể làm một cái gì đó như:

MyNum = 5; 
TryParsing(myString, &myNum); 

trong khi mã mà không muốn sử dụng một giá trị mặc định có thể sử dụng:

if (TryParsing(myString, &myNum)) 
{ .. code that uses myNum .. } 
else 
{ .. code that doesn't use myNum .. } 

Trong lần sử dụng cũ, mã gọi điện sẽ phải đảm bảo myNum được khởi tạo trước cuộc gọi, nhưng sẽ không phải lo lắng về giá trị trả về TryParsing. Trong lần sử dụng thứ hai, mã gọi sẽ phải lo lắng về giá trị trả về, nhưng sẽ không phải khởi tạo myNum trước cuộc gọi. Các TryParsing thường xuyên chính nó sẽ không phải lo lắng về việc sử dụng được dự định.

C# không cho phép mẫu như vậy, trừ khi TryParsing được viết bằng ngôn ngữ khác. Hoặc là TryParsing phải được viết theo cách mà giá trị trước đó của myNum sẽ bị ghi đè vô điều kiện mà không được kiểm tra, người gọi phải vô điều kiện khởi tạo nó hoặc các phương thức khác nhau phải được cung cấp cho hai trường hợp. Nếu phương pháp TryParsing được viết bằng một số ngôn ngữ khác, nó có thể trong lý thuyết hành xử giống như các phương pháp kiểu cũ (viết đối số thành công, và để nó một mình nếu không) trong khi vẫn gọi nó là tham số out. Tuy nhiên, tôi sẽ không khuyến nghị điều này vì hành vi kỳ quặc sẽ không bị giới hạn trong tham số out đó.

Xem xét, ví dụ, rằng một phương pháp phong cách mà sử dụng một đối số kiểu fooStruct, và fooStruct có một constructor mà trông giống như:

fooStruct(string st) 
{ 
    fooStruct.TryParse(st, out this); 
} 

Trình biên dịch sẽ được hoàn toàn hạnh phúc với một constructor như vậy, kể từ nó "chắc chắn" viết this. Mặt khác, nếu một số mã khác không:

while(someCondition) 
{ 
    var s = new fooStruct(someString); 
    ... 
} 

Người ta có thể hy vọng rằng s hoặc sẽ tổ chức một cấu trúc khởi tạo (nếu someString là hợp lệ) hoặc để trống (nếu nó không phải là). Không có gì về mã đó sẽ gợi ý rằng s có thể giữ giá trị của nó giữa các lần lặp lại của vòng lặp. Tuy nhiên, đó là chính xác những gì có thể sẽ xảy ra.

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