如何在 C# 中检查方法的返回类型是否可为空(启用完全可为空上下文)

问题描述 投票:0回答:1

如何检查方法的返回类型是否可为空? 项目设置

<Nullable>enable</Nullable>
已激活。

一些示例(所有方法均为

Task
Task<T>
类型)

public sealed class Dto
{
    public int Test { get; set; }
}

public sealed class Dto3
{
    public int? Test { get; set; }
}

public async Task<Dto?> GetSomething()
{
    // This should be found as "Nullable enabled" as the `?` is set.
}

public async Task<Dto3> GetSomething2()
{
    // This should not be found as "Nullable enabled" as the `?` is missing.
}

public async Task<List<Dto>> GetSomething3()
{
    // This should not be found as "Nullable enabled" as the `?` is missing
    // (And the list must be initialized anyways thanks to nullable context).
}

public async Task<List<Dto?>> GetSomething3()
{
    // This should not be found as "Nullable enabled" as the `?` is missing in the first generic type after `Task`.
}

我已经有了迭代搜索命名空间中的类和方法的代码,如下所示:

var assembly = Assembly.GetAssembly(typeof(ISomethingService));

if (assembly is null)
{
    throw new InvalidOperationException("This should never happen");
}

var classes = assembly.GetTypes().Where(type => 
 (type.Namespace == typeof(ISomethingService).Namespace || type.Namespace == typeof(ISomethingService2).Namespace) && type.IsInterface);

foreach (var @class in classes)
{
    var methods = @class.GetMethods();

    foreach (var method in methods)
    {
        foreach (var genericType in method.ReturnType.GenericTypeArguments)
        {
            if (IsNullable(genericType))
            {
                Console.WriteLine($"Return type of method {@class.Name}.{method.Name} is nullable: {genericType.Name}");
            }
        }
    }
 }

可为空检查目前是这样实现的,但没有按预期工作:

private static bool IsNullable<T>(T obj)
{
    if (obj == null) return true; // obvious
    Type type = typeof(T);
    if (!type.IsValueType) return true; // ref-type
    if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable<T>
    return false; // value-type
}

有没有办法达到预期的结果(例如,如果在

IsNullable
之后的第一级(泛型)设置了
true
,则只有
?
Task<T>

c# nullable
1个回答
0
投票

在 .NET 6+ 中,您可以使用

NullabilityInfoContext
来查明字段、属性、参数或事件是否可为 null。另请参阅此答案

在您的情况下,您想要获取该方法的

ReturnParameter
,这是一个
PropertyInfo

bool ReturnNullableOrNullableTask(MethodInfo m) {
    var context = new NullabilityInfoContext();
    var returnParameter = m.ReturnParameter;
    var info = context.Create(returnParameter);
    if (info.ReadState == NullabilityState.Nullable) {
        return true; // the return type itself is null
    }
    // otherwise check if it is a Task<T>
    if (returnParameter.ParameterType == typeof(Task<>)) {
        var firstTypeParameterInfo = info.GenericTypeArguments[0];
        if (firstTypeParameterInfo.ReadState == NullabilityState.Nullable) {
            return true;
        }
    }
    return false;
}

这适用于可为空值类型和可为空引用类型。

© www.soinside.com 2019 - 2024. All rights reserved.