【发布时间】:2009-12-31 23:33:32
【问题描述】:
我知道 C# 关键字 var 在编译时暗示了类型,因此需要在同一位置声明和赋值,从而使以下构造非法:
var something;
if (condition)
{
something=1;
}
else
{
something = 0;
}
尽管 C# 编译器原则上可以确定当前作用域中的所有赋值都产生相同的类型,但它(目前)不能,因此会产生编译时错误。
在将 var 与 LINQ 一起使用时,我有时希望根据程序条件对结果变量进行稍微不同的初始化。我发现的方法是使用 ?: 运算符,如:
var participants = (email == null ?
(from part in db.Participant
where part.SequenceNumber == seqNr
select part)
:
(from part in db.Participant
where part.EmailAddress == email
select part));
如果我只有两个可能的分配,那效果很好,但如果有多个可能的分配,很快就会变得笨拙。
有没有更优雅的方法来解决这个问题?
【问题讨论】:
-
嗯,有些语言允许在 var 声明点之后进行推理...
-
如果 C# 在某些时候没有更聪明地进行类型推断,那会让我感到惊讶。只要当前作用域内的所有赋值都尝试同时赋值,编译器就可以处理这种情况。
-
我同意原则上可以做到这一点,但在实践中它比你的快速草图所表明的要复杂得多。 var 不仅要求有一个初始化器,它还要求初始化器不引用变量。如果你有 int M(out int) 那么你可以说“int x = M(out x);”但你不能说“var x = M(out x);”因为要对 M 进行重载解析,我们需要知道 x 的类型,这正是我们试图弄清楚的。说“var s; if (b) M(out s); else s = 0;”是否合法? ?
-
C#3 类型推断器不是我见过的最聪明的。大多数函数式语言要好得多,而且 haXe 作为一种命令式语言,具有非常强大的推断器,它也可以推断超出初始化点。例如,在 Eric Lippert 的案例中,类型将取决于之后的用途。如果它被用作一些 int 类型的函数参数,则 var 将被推断为 int。编译器只是查看它使用的每个地方,它是什么类型,并据此推断类型。如果需要动态。
-
其实就是这个定理。推断器有点缺陷。
标签: c# type-inference