C# Nullable<T> 查询理解 - "expression is always true"警告

标签 c# linq resharper monads

我通过为 Nullable<T> 编写 Select 和 SelectMany 实现来取乐自己输入 C#(启用 LINQ 查询理解语法。当我编写一些测试查询时,编译器会给我一个警告:

public static void Test()
{
    var z1 =
        from x in 5.Nullable()
        from y in 6.Nullable()
        select x + y;

    var z2 =
        from x in 3.Nullable()
        from y in default(DateTime?)
        select y.Month == x;

    var result =
        from x in z1
        from y in z2
        select x == 11 && !y;

    Console.WriteLine(result.HasValue // <-- this expression is "always true"
        ? result.Value.ToString()
        : "computation failed");
}

它怎么能这样声明呢?我知道它没有解释上面的查询,因为如果我更改代码,那么 HasValue 应该为假(例如,将 z1 中的 x 更改为 20),它仍然会发出警告。这是编译器中的错误还是我犯了错误?

我相信我的方法实现是正确的,但这里仅供引用:

public static T? Nullable<T>(this T x)
    where T : struct 
{
    return x;
}

public static U? Select<T, U>(this T? n, Func<T, U> f)
    where T : struct
    where U : struct
{
    return n.HasValue
        ? f(n.Value)
        : default(U?);
}

public static U? SelectMany<T, U>(this T? n, Func<T, U?> f)
    where T : struct
    where U : struct
{
    return n.HasValue
        ? f(n.Value)
        : default(U?);
}

public static V? SelectMany<T, U, V>(this T? n, Func<T, U?> f, Func<T, U, V> g)
    where T : struct
    where U : struct
    where V : struct
{
    if (!n.HasValue) return default(V?);

    var u = f(n.Value);
    return u.HasValue
        ? g(n.Value, u.Value)
        : default(V?);
}

最佳答案

ReSharper 警告显然不准确。考虑一下您的代码的这种变体:

var z1 =
    from x in default(int?)
    from y in 6.Nullable()
    select x + y;

if (z1.HasValue)
{
}

ReSharper 会将条件标记为“始终为真”:

enter image description here

但在调试器中我们可以清楚地看到它是错误的:

enter image description here

所以我会说这是 ReSharper 中的一个错误。


(供将来引用,it has been submitted by the OP to the issue tracker。)

关于C# Nullable<T> 查询理解 - "expression is always true"警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37324314/

相关文章:

c# - 使用 HttpClient 发送大量请求的最快和最安全的方法是什么?

c# - ASP .NET 获取数据太慢

c# - 如何使用 Resharper 结构查找和替换将 C# 对象初始值设定项转换为使用构造函数

c# - 在任务中调用 CancellationTokenSource.Cancel() 不会将 Task.IsCanceled 设置为 true

c# - Resharper 关闭类型提示

c# - 程序集绑定(bind)和重定向

c# - 复杂类型的子集和

c# - 无法将类型为 'System.Linq.Expressions.UnaryExpression' 的对象转换为类型 'System.Linq.Expressions.MemberExpression'

c# - Linq:对列表进行分组,对其进行排序并获得最高的 x 值?

c# - 微软.AspNetCore.OData 8 : controller is not found by convention