gpt4 book ai didi

c# - 空合并参数给出意外警告

转载 作者:太空狗 更新时间:2023-10-29 20:58:09 25 4
gpt4 key购买 nike

使用这个构造:

var dict = new Dictionary<int, string>();
var result = (dict?.TryGetValue(1, out var value) ?? false) ? value : "Default";

我收到一条错误消息,提示 CS0165 使用未分配的局部变量“value”,这不是我所期望的。 value 怎么可能是未定义的?如果字典为空,内部语句将返回 false,这将使外部语句计算为 false,返回 Default

我在这里错过了什么?仅仅是编译器无法完全评估语句吗?还是我搞砸了?

最佳答案

您的分析是正确的。它不是编译器进行的分析,因为编译器进行的分析是 C# 规范所要求的。分析如下:

  • 如果 condition?consequence:alternative 的条件表达式是编译时常量 true那么备选分支是不可达的;如果false ,则结果分支不可达;否则,两个分支都是可达的。

  • 这种情况下的条件不是常数,因此结果和备选方案都是可达的。

  • 局部变量 value仅在 dict 时明确分配不为空,因此 value当结果达到时,未明确分配

  • 但是结果需要value明确分配

  • 所以这是一个错误。

编译器没有你那么聪明,但它是C#规范的准确实现。 (请注意,我没有在这里勾勒出针对这种情况的额外特殊规则,其中包括谓词,如“在真表达式之后明确赋值”等。有关详细信息,请参阅 C# 规范。)

顺便说一句,C# 2.0 编译器太聪明了。例如,如果您有类似 0 * x == 0 的条件对于一些 int local x它会推断出“无论 x 的值是什么,该条件始终为真”并将替代分支标记为不可访问。该分析在与现实世界相匹配的意义上是正确的,但在 C# 规范明确指出仅对编译时常量进行推导以及同样明确指出涉及 变量不是常量

记住,这东西的目的是找bug,还有什么更有可能呢?有人写了0 * x == 0 ? foo : bar打算它的意思是“总是foo”,或者他们不小心写了一个错误?我修复了编译器中的错误,从那时起它就严格符合规范。

在你的情况下没有错误,但代码太复杂了,编译器无法分析,所以它可能也太复杂了,无法期望人类来分析。看看你能不能简化它。我可能会做的是:

public static V GetValueOrDefault<K, V>(
this Dictionary<K, V> d,
K key,
V defaultValue)
{
if (d != null && d.TryGetValue(key, out var value))
return value;
return defaultValue;
}

var result = dict.GetValueOrDefault(1, "Default");

目标应该是使调用站点可读;我认为我的调用站点比您的更具可读性。

关于c# - 空合并参数给出意外警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55207014/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com