我通过为 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 会将条件标记为“始终为真”:
但在调试器中我们可以清楚地看到它是错误的:
所以我会说这是 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/