Как преобразовать IList ‹T?› В IList ‹T› в ссылочном типе C # 8, допускающем значение NULL

Описание проблемы

Я работаю с ссылочными типами C # 8 и Nullable.

Я получаю предупреждения с помощью такого метода:

private IList<Person?> persons;

// some initialisations here....

IList<Person> GetPersons()
{
   return someList.Where(t => t != null).ToList();
}

Предупреждение:

[CS8619] Nullability of reference types in value of type 
'IList<Person?>' doesn't match target type 'IList<Person>'.

Я также пробовал следующее:

return someList.Where(t => t != null).Select(t => t!).ToList();

Но я получил такое же предупреждение !!

Решение (неудачное)

Единственный обходной путь, который я нашел, заключался в следующем:

IList<Person> GetPersons()
{
   return someList.Where(t => t != null).Select(t => Some(t)).ToList();
}

// THIS REMOVES THE WARNING
private Person Some(Person? person) => person!;

Однако, если я хочу сделать его универсальным, это не сработает .... Я снова получаю предупреждение, и этот метод возвращает Person?

private T Some<T>(T? t) where T: class => t!;

person Ricky Youssef    schedule 27.01.2020    source источник


Ответы (2)


Используйте в выражении оператор, допускающий нулевое значение, он применяется ко всему выражению и любому из вложенных типов (т. Е. Универсальному параметру списка). Или просто приведите к версии, не допускающей значения NULL.

IList<Person> GetPersons() => someList.Where(t => t != null).ToList()!;

// or

IList<Person> GetPersons() => (IList<Person>)someList.Where(t => t != null).ToList();

Проверьте документацию по предложению:

https://github.com/dotnet/csharplang/blob/master/proposals/csharp-8.0/nullable-reference-types.md#checking-of-nullable-references

В основном преобразование из IList<Person?> в IList<Person> будет рассматриваться как имеющее пустую ссылку и генерировать предупреждения. Но при использовании оператора, допускающего нулевое значение, он обрабатывается как имеющий ненулевую ссылку (отрицание предупреждения).

person Jeff Mercado    schedule 27.01.2020

В объявлении вашего метода есть несоответствие.

Попробуйте изменить это:

IList<Person> GetPersons()

к этому:

IList<Person?> GetPerson
person Merkle Groot    schedule 27.01.2020
comment
Вопрос спрашивает, как не этого делать, поскольку метод уже гарантирует, что результаты не равны нулю. - person Panagiotis Kanavos; 27.01.2020