我们可以把一个属性应用到委托的参数上吗?

编程语言 2026-07-08

在较新版本的.NET中,编译器提供了一个功能,可以为带有参数属性的lambda表达式生成委托类型,我记得是通过分析器实现的。尤其是在ASP.NET Core的 Minimal API的端点定义中。

就像这样:

app.MapGet("/data", ([FromQuery] int? id) => ...);

然而,我认为我遇到了相反的问题。我有一个调试扩展,能够基于任意条件添加一个条件消息。源对象会被原样传递。我想继续遵守空性检查,并指示 condition 函数的输入可能为null,也可能不为null,这取决于 source 的可空性。我已经把它应用到返回值上。但我想在函数中声明,传入的委托可以使用 source 的可空性。

public static class DebugExtensions
{
    [return: NotNullIfNotNull(nameof(source))] // targets return value
    public static T? Debug<T>(this T? source,
        [dparam0: NotNullIfNotNull(nameof(source))] // try to target delegate parameter (not valid)
        Func<T?, bool> condition, // Can I apply NotNullIfNotNull on the T? parameter of condition from here?
        object? obj,
        [CallerArgumentExpression(nameof(condition))]
        string? expr = default)
    {
        if (condition(source))
            obj.Dump(expr);
        return source;
    }
}

如果没有该属性,调用者将收到这样的警告:参数可能为null,而我们知道它肯定不是。

string definitelyNotNullConnectionString = "some connection string";

o.ConnectionString = definitelyNotNullConnectionString
    .Debug(s => s.Contains("Data Source=someserver"), $"Found the connection string: {definitelyNotNullConnectionString}");
//              ^ CS8602 dereference of possibly null reference

是否可以在委托的一个参数上应用属性?

解决方案

别想太多。只要让调用者告诉你泛型类型参数是否可空就行。

#nullable enable
public static void Debug<T>(this T source, Func<T, bool> condition) { }

public static void Test()
{
    int a = 1;
    int? b = 1;
    string c = "1";
    string? d = default;

    a.Debug(s => s.CompareTo(2) == 0);
    b.Debug(s => s?.CompareTo(2) == 0);
    c.Debug(s => s.CompareTo("2") == 0);
    d.Debug(s => s?.CompareTo("2") == 0);
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章