2009-04-10 36 views
7

Tôi đã viết các phương pháp sau để trả về một danh sách các lớp Unserializable (lớp LINQ) từ một danh sách các lớp Serializable (POCOs):C#: 'mặc định' từ khóa với Generics

List<UnSerializableEntity> ToListOfUnserializables(List<SerializableEntity> entityList) 
{ 
    var tempList = new List<UnSerializableEntity>(); 
    entityList.ForEach(e => 
    { 
     if (e != null) 
     { 
      tempList.Add(ConvertFromSerializableToUnserializable(e)); 
     } 
    }); 
    return tempList; 
} 

Bây giờ, Resharper có ' phàn nàn' về dòng này: if (e != null), và gợi ý để thay đổi nó như thế này:

if (!Equals(e, default(SerializableEntity))) 

câu hỏi của tôi là để những gì đã thay đổi này thực sự được cải thiện hoặc ngăn ngừa xảy ra? và tôi biết từ khóa mặc định trong ngữ cảnh này phải làm một cái gì đó với generics, nhưng tôi không chắc chắn những gì nó đại diện chính xác.

PS. UnSerializableEntitySerializableEntity là lớp học chung.

Trả lời

13

Nếu SerializableEntity là loại giá trị, nó không bao giờ có thể là null. Do đó, nội dung câu lệnh if của bạn sẽ luôn luôn thực thi vì nó đang kiểm tra null. Từ khóa default sẽ trả lại giá trị mặc định của loại chung. Đối với các loại tham chiếu, giá trị mặc định là null. Đối với các loại giá trị, nó là số không (hoặc bất kỳ số không đại diện cho loại giá trị đó).

Nếu bạn chỉ muốn tham chiếu các loại dưới dạng thực thể, bạn nên đặt ràng buộc về các thông số chung của mình. Ví dụ: phản ứng

List<UnSerializableEntity> ToListOfUnserializables(List<SerializableEntity> entityList) 
    where SerializableEntity : class 
+0

Nhưng câu lệnh if của anh ấy đã kiểm tra giá trị đó là _không null, điều đó có nghĩa là luôn luôn thực hiện? – sisve

+0

Khối "if" sẽ không bao giờ thực thi: các kiểu giá trị sẽ ném một ngoại lệ. –

+0

@Simon tuyên bố e! = Null và! Equals (e, mặc định (SerializableEntity)) đều đúng khi e không phải là null/default –

4

Kent là chính xác, nhưng để trả lời câu hỏi của bạn một cách rõ ràng hơn về Resharper và tại sao nó phàn nàn:

Trong trường hợp của một loại tài liệu tham khảo (class) một tấm séc for null sẽ là đủ, vì đó được coi là giá trị "mặc định" cho loại tham chiếu. Tuy nhiên, đối với một loại giá trị (chẳng hạn như cấu trúc), "mặc định" sẽ KHÔNG BAO GIỜ là rỗng. Do đó, vì SerializableEntity và UnSerializableEntity của bạn là generics, bạn có thể chỉ định chúng là một trong hai kiểu tham chiếu hoặc giá trị, vì vậy việc kiểm tra null việc bạn làm có lẽ không phải là thứ bạn muốn. Những gì bạn muốn kiểm tra là đảm bảo rằng tham số là thứ bạn thực sự muốn quan tâm. Trong trường hợp của một kiểu tham chiếu, bạn không muốn quan tâm đến chính mình với các đối tượng null. Trong trường hợp của một loại giá trị, bạn không muốn quan tâm đến mình với một giá trị "zeroed out".

Ví dụ: Giả sử bạn chỉ định một DateTime là kiểu dữ liệu bạn đang làm việc với. Bạn có thực sự muốn thêm Ngày giờ không có bất kỳ giá trị nào được đặt không? Giá trị mặc định cho DateTime là 1/1/0001, không phải là null, vì vậy bạn cần phải kiểm tra xem có sử dụng if (!Equals(e, default(SerializableEntity))) không if (e != null)

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