C #: ключевое слово «по умолчанию» с Generics - PullRequest
7 голосов
/ 10 апреля 2009

Я написал следующий метод для возврата списка несериализуемых классов (классов LINQ) из списка сериализуемых классов (POCO):

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

Теперь Resharper «пожаловался» на эту строку: if (e != null) и предложил изменить ее на:

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

У меня вопрос к что на самом деле улучшило или предотвратило это изменение? и я знаю, что ключевое слово по умолчанию в этом контексте связано с обобщениями, но я не уверен, что именно оно представляет .

PS. UnSerializableEntity и SerializableEntity являются родовыми типами классов.

Ответы [ 2 ]

13 голосов
/ 10 апреля 2009

Если SerializableEntity является типом значения, оно никогда не может быть null. Следовательно, тело вашего оператора if всегда будет выполняться, поскольку оно проверяет null. Ключевое слово default вернет значение по умолчанию универсального типа. Для ссылочных типов значением по умолчанию является null. Для типов значений это ноль (или любой другой ноль, представленный для этого типа значения).

Если вы хотите, чтобы ссылочные типы были только сущностями, вы должны установить ограничения на ваши общие параметры. Например:

List<UnSerializableEntity> ToListOfUnserializables(List<SerializableEntity> entityList)
    where SerializableEntity : class
4 голосов
/ 14 апреля 2009

Ответ Кента точен, но чтобы ответить на ваш вопрос более четко о Решарпере и почему он жалуется:

В случае ссылочного типа (класса) будет достаточно проверки на нулевое значение, поскольку это считается значением по умолчанию для ссылочного типа. Однако для типа значения (такого как структура) «default» НИКОГДА не будет нулевым. Следовательно, поскольку ваши SerializableEntity и UnSerializableEntity являются обобщенными, вы можете указать, что они являются ссылочными типами или типами значений, поэтому нулевая проверка, вероятно, не соответствует вашим ожиданиям. Что вы хотели бы проверить, так это убедиться, что параметр - это то, чем вы действительно хотите заниматься. В случае ссылочного типа вы не хотите заниматься нулевыми объектами. В случае типа значения вы не хотите беспокоиться о «обнуленном» значении.

Например: допустим, вы указали DateTime в качестве типа данных, с которым имеете дело. Вы действительно хотите добавлять DateTimes, для которых не установлено никакого значения? Значением по умолчанию для DateTime является 1/1/0001, а не NULL, поэтому вам нужно проверить это, используя if (!Equals(e, default(SerializableEntity))), а не if (e != null)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...