简体   繁体   中英

Null Check Operator still returns a null value

I'm trying to get all of the generic service from my dependency injector who implement a type

protected List<ServiceDescriptor> GetGenericServicesFromGenericTypeDefinition(IServiceCollection services, Type baseGenericTypeDefinition)
{
    if(false == baseGenericTypeDefinition.IsGenericTypeDefinition)
    {
        throw new Exception($"Invalid Argument {nameof(baseGenericTypeDefinition)}");
    }

    //TODO:  check the base type recursively
    var genericImplementations = services.Where(s => s?.ImplementationType.GetTypeInfo().IsGenericType ?? false)
            .ToList();
    //.... Omitted unrelated to issue
}

The wierd thing is that when it tries to create genericImplementations List I receive an Error

System.ArgumentNullException: 'Value cannot be null.'

I've checked the service it is not null, the Implementation type is however. How is this possible, Is this some how related to how the func is constructed? 在此输入图像描述

EDIT How am I using the Elvis Operator wrong? s has a value as you can see. from the picture. The error is generating from the type checked how is this possible?

The ?. operator refers only to the dereferencing operation it is applied to. When not only s can be null , but also s.ImplementationType , the expression...

s?.ImplementationType.GetTypeInfo()

...won't be enough. You need to use the operator in all places where the expression to the left can be null :

s?.ImplementationType?.GetTypeInfo()

Since the return of GetTypeInfo() can not be null , it is enough to write:

s?.ImplementationType?.GetTypeInfo().IsGenericType ?? false

It's a good idea not to generally apply the ?. to all dereferences, but to use it only when the value could be null and skipping the rest of the expression is OK. If you apply the operator generally in all cases, errors might fall through that otherwise would get caught early.

您必须在每个成员访问和成员调用时使用null检查运算符来传播任何级别的空值,如下所示:

var genericImplementations = services.Where(s => s?.ImplementationType?.GetTypeInfo()?.IsGenericType ?? false).ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM