2008-11-19 44 views
418

Tôi có một phương pháp chung với mã (giả) này (có tôi biết IList có biến vị ngữ, nhưng mã của tôi không sử dụng IList nhưng một số bộ sưu tập khác, dù sao điều này không liên quan cho câu hỏi ...)Làm thế nào tôi có thể trả về NULL từ một phương thức chung trong C#?

static T FindThing<T>(IList collection, int id) where T : IThing, new() 
{ 
    foreach T thing in collecion 
    { 
     if (thing.Id == id) 
      return thing; 
    } 
    return null; // ERROR: Cannot convert null to type parameter 'T' because it could be a value type. Consider using 'default(T)' instead. 
} 

này mang lại cho tôi một lỗi build

"không thể chuyển đổi null để gõ tham số 'T' bởi vì nó có thể là một kiểu giá trị. Xem xét sử dụng 'mặc định (T) để thay thế."

Tôi có thể tránh lỗi này không?

+1

tại sao wiki cộng đồng này lại là? – vitule

+2

Nguyên nhân khiến tôi có thể chỉnh sửa cộng đồng câu hỏi này? – edosoft

Trả lời

741

Hai lựa chọn:

  • Return default(T) có nghĩa là bạn sẽ trở null nếu T là một loại tài liệu tham khảo (hoặc một loại giá trị nullable), 0 cho int, '\ 0' cho char vv
  • Giới hạn T trở thành một loại tài liệu tham khảo với where T : class hạn chế và sau đó trở về null như bình thường
+3

Điều gì xảy ra nếu kiểu trả về của tôi là một enum không phải là một lớp? Tôi không thể chỉ định T: enum :( – Justin

+1

Trong .NET một enum là một wrapper rất mỏng (và khá rò rỉ) xung quanh một loại nguyên.Thông ước là sử dụng số không cho giá trị enum "mặc định" của bạn –

+18

Tôi nghĩ rằng vấn đề với điều này là nếu bạn đang sử dụng phương thức chung này để nói, chuyển đổi một đối tượng Cơ sở dữ liệu từ DbNull sang Int và nó trả về mặc định (T) trong đó T là int, nó sẽ trả về 0. Nếu số này thực sự có ý nghĩa thì Nếu một trường nào đó giống như "DateClosed" và nó được trả về là null vì tài khoản vẫn mở, nó sẽ thực sự mặc định (DateTime) đến 1/1/0000, ngụ ý rằng tài khoản đã bị đóng trước khi các máy tính được phát minh – Sinaesthetic

61
return default(T); 
+0

Liên kết này: http://msdn.microsoft.com/en-us/library/xwth0h0d(VS.80).aspx nên giải thích lý do. –

+0

Chết tiệt, tôi đã tiết kiệm rất nhiều thời gian mà tôi đã biết về từ khóa này - cảm ơn Ricardo! –

+0

Tôi ngạc nhiên rằng điều này đã không nhận được nhiều phiếu bầu hơn vì từ khóa 'mặc định' là một giải pháp toàn diện hơn, cho phép sử dụng các loại không tham chiếu kết hợp với các loại và cấu trúc số. Trong khi câu trả lời được chấp nhận giải quyết vấn đề (và thực sự là hữu ích), thì nó sẽ trả lời tốt hơn cách hạn chế kiểu trả về thành các kiểu tham chiếu nullable/reference. –

1

Đưa ra đề xuất về lỗi ... và người dùng default(T) hoặc new T.

Bạn sẽ phải thêm so sánh trong mã của mình để đảm bảo rằng đó là một kết hợp hợp lệ nếu bạn đi theo tuyến đường đó.

Nếu không, có khả năng xem xét thông số đầu ra cho "kết quả được tìm thấy".

5

tùy chọn khác của bạn sẽ được để thêm video này vào cuối khai của bạn:

where T : class 
    where T: IList 

Bằng cách đó, nó sẽ cho phép bạn trả về giá trị rỗng.

22

Bạn chỉ có thể điều chỉnh những hạn chế của bạn:

where T : class, IDisposable 

rỗng Sau đó quay trở lại được cho phép.

+0

Cảm ơn. Tôi không thể chọn 2 câu trả lời là giải pháp được chấp nhận, vì vậy tôi chọn John Skeet khiến câu trả lời của anh ấy có hai giải pháp. – edosoft

+5

Hơi sai, nó không phải là IDisposable ... – Migol

10

Thêm ràng buộc lớp làm ràng buộc đầu tiên cho loại chung của bạn.

static T FindThing<T>(IList collection, int id) where T : class, IThing, new() 
+0

Cảm ơn. Tôi không thể chọn 2 câu trả lời là giải pháp được chấp nhận, vì vậy tôi chọn John Skeet khiến câu trả lời của anh ấy có hai giải pháp. – edosoft

1

giải pháp của TheSoftwareJedi hoạt động,

bạn cũng có thể lưu trữ nó với việc sử dụng vài giá trị và nullable loại:

static T? FindThing<T>(IList collection, int id) where T : struct, IThing 
{ 
    foreach T thing in collecion 
    { 
     if (thing.Id == id) 
      return thing; 
    } 
    return null; 
} 
5
  1. Nếu bạn có đối tượng thì cần phải định kiểu

    return (T)(object)(employee); 
    
  2. nếu bạn cần trả về null.

    return default(T); 
    
+0

Xin chào user725388, vui lòng xác minh tùy chọn đầu tiên –

1

Dưới đây là một ví dụ làm việc cho các giá trị trở lại Nullable Enum:

public static TEnum? ParseOptional<TEnum>(this string value) where TEnum : struct 
{ 
    return value == null ? (TEnum?)null : (TEnum) Enum.Parse(typeof(TEnum), value); 
} 
1

Dưới đây là hai tùy chọn mà bạn có thể sử dụng

return default(T); 

hoặc

where T : class, IDisposable 
return null; 
Các vấn đề liên quan