Có một mẫu trong các lớp C # được minh họa bằng Dictionary.TryGetValue
và int.TryParse
: một phương thức trả về một boolean biểu thị sự thành công của một hoạt động và một tham số out chứa kết quả thực tế; nếu hoạt động thất bại, tham số out được đặt thành null.
Giả sử tôi đang sử dụng các tài liệu tham khảo không có giá trị C # 8 và muốn viết một phương thức TryPude cho lớp của riêng tôi. Các đúng chữ ký là thế này:
public static bool TryParse(string s, out MyClass? result);
Vì kết quả là null trong trường hợp sai, biến out phải được đánh dấu là null.
Tuy nhiên, mẫu Thử thường được sử dụng như thế này:
if (MyClass.TryParse(s, out var result))
{
// use result here
}
Bởi vì tôi chỉ nhập chi nhánh khi hoạt động thành công, kết quả sẽ không bao giờ là null trong chi nhánh đó. Nhưng vì tôi đã đánh dấu nó là nullable nên giờ tôi phải kiểm tra hoặc sử dụng !
để ghi đè:
if (MyClass.TryParse(s, out var result))
{
Console.WriteLine("Look: {0}", result.SomeProperty); // compiler warning, could be null
Console.WriteLine("Look: {0}", result!.SomeProperty); // need override
}
Điều này là xấu xí và một chút không kinh tế.
Do kiểu sử dụng điển hình, tôi có một tùy chọn khác: nói dối về loại kết quả:
public static bool TryParse(string s, out MyClass result) // not nullable
{
// Happy path sets result to non-null and returns true.
// Error path does this:
result = null!; // override compiler complaint
return false;
}
Bây giờ cách sử dụng thông thường trở nên đẹp hơn:
if (MyClass.TryParse(s, out var result))
{
Console.WriteLine("Look: {0}", result.SomeProperty); // no warning
}
nhưng việc sử dụng không điển hình không nhận được cảnh báo nên:
else
{
Console.WriteLine("Fail: {0}", result.SomeProperty);
// Yes, result is in scope here. No, it will never be non-null.
// Yes, it will throw. No, the compiler won't warn about it.
}
Bây giờ tôi không chắc đường nào để đến đây. Có một khuyến nghị chính thức từ nhóm ngôn ngữ C #? Có bất kỳ mã CoreFX nào đã được chuyển đổi thành các tham chiếu không thể rỗng có thể chỉ cho tôi cách thực hiện điều này không? (Tôi đã đi tìmTryParse
phương thức. IPAddress
Là một lớp có một, nhưng nó chưa được chuyển đổi trên nhánh chính của corefx.)
Và làm thế nào để mã chung như Dictionary.TryGetValue
đối phó với điều này? (Có thể với một MaybeNull
thuộc tính đặc biệt từ những gì tôi tìm thấy.) Điều gì xảy ra khi tôi khởi tạo a Dictionary
với loại giá trị không thể rỗng?
MyClass?
) và thực hiện một chuyển đổi trên nó với mộtcase MyClass myObj:
và (một tùy chọn)case null:
.