我们可以把一个属性应用到委托的参数上吗?
在较新版本的.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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。