编程语言
首页 > 编程语言> > C#Nullable查询理解 – “表达始终为真”警告

C#Nullable查询理解 – “表达始终为真”警告

作者:互联网

我通过编写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,linq,monads,resharper
来源: https://codeday.me/bug/20190628/1311386.html