![]() |
1
9
你只能用
在所有其他地方,您必须指定一个类型,即使理论上可以推导出一个类型。
原因是编译器的设计方式。一个简单的描述是,它首先解析除方法体之外的所有内容,然后对每个类、成员等的静态类型进行完整的分析。然后在分析方法体时使用此信息,特别是用于推导声明为
您可以阅读Eric Lippert关于此主题的文章,了解更多详细信息: |
![]() |
2
7
因为编译器通过查看赋值的右边来确定实际的类型。例如,这里确定它是一个字符串:
在这里决定
在方法参数中,没有“赋值的右侧”,因此不能使用var。 |
![]() |
3
7
见 posting by Eric Lippert 关于字段上不允许使用var的原因,该字段还包含为什么它在方法签名中不起作用的解释:
|
![]() |
4
7
请看朱丽叶的回答,以便更好地回答这个问题。 因为在C中添加完整的类型推断太难了。 其他语言(如haskell和ml)可以自动推断最一般的类型,而无需声明它。 另一个答案指出编译器“不可能”推断VaR的类型,但实际上原则上是可能的。例如:
让“var”方法参数原则上与通用方法相同:
不幸的是,您不能对两者都使用相同的语法,但这可能是因为C的类型推断是在以后才添加的。 一般来说,语言语法和语义的细微变化可以将“确定性”类型推理算法转变为不可确定的类型推理算法。 |
![]() |
5
6
ml、haskell、scala、f_、sml和其他语言可以很容易地从自己语言中的等价表达式中找出类型,这主要是因为它们从一开始就在设计时就考虑了类型推断。C不是,它的类型推断是作为访问匿名类型问题的一个临时解决方案附加上去的。 我推测,真正的Hindley-Milner类型推断从来没有为C实现过,因为在一种如此依赖类和继承的语言中推导类型很复杂。假设我有以下课程:
现在我有了这个方法:
这里的退货类型是什么?它是
好吧,现在假设我有这个方法:
第一次呼叫,
第二个电话呢?
不能基于函数的用法来概括更广泛的类型。你基本上需要确定一个单一的混凝土类型,一旦你知道哪一种混凝土类型正在通过。所以在上面的示例代码中,除非显式转换为基类型,
现在,这里的诀窍是确定一种类型。这里发生了什么:
什么类型的
在不更改c的语义的情况下解析类型是不可能的。在C中,方法声明的顺序对编译没有影响(或者至少不应该影响;)。您可以说方法首先声明(在本例中,是
这是可行的,但它也改变了c的语义:方法顺序的改变将改变方法的编译类型。 但我们更进一步:
现在正从不同的文件调用这些方法。什么类型的?在没有对编译顺序施加某些规则的情况下,无法决定:如果foo.cs在bar.cs之前编译,则类型由foo.cs确定。 而我们 可以 将这些规则强加于C上,以使类型推断工作,这将极大地改变语言的语义。 相比之下,ml、haskell、f_和sml非常支持类型推断。 因为 它们有这些限制:在声明方法之前不能调用方法,对推断函数的第一个方法调用确定类型,编译顺序对类型推断有影响等等。 |
![]() |
6
1
“var”关键字在c和vb.net中用于 类型推断 -你基本上告诉C编译器:“你知道类型是什么”。 “var”仍然是强类型的——你太懒惰了,无法写出类型并让编译器来计算它——基于赋值右侧的数据类型。 在这里,在一个方法参数中,编译器无法弄清楚您真正的意思。怎样?你真正的意思是什么类型的?编译器无法从方法定义中推断类型,因此它不是有效的语句。 |
![]() |
7
1
因为C是类型安全的
坚强的
类型语言。在程序编译器的任何地方,总是知道您使用的参数类型。
|
![]() |
8
0
检查
|
![]() |
9
0
类型推理是类型推理,可以是局部表达式,也可以是全局/过程间的。所以这不是“没有右手边”,因为在编译器理论中,过程调用是“右手边”的一种形式。 如果编译器进行了全局类型推断,C可以这样做,但它没有。 如果需要接受任何内容的参数,可以使用“object”,但是需要自己处理运行时转换和潜在的异常。 C中的“var”不是运行时类型绑定,它是一个编译时功能,最终得到一个非常特定的类型,但C类型推断的范围有限。 |
![]() |
A B · C#Excel自动调整列避免长文本时出错 5 月前 |
|
pseudodev · 失败的测试仅显示堆栈跟踪,不显示完整日志 6 月前 |
![]() |
CactusCake · if语句中应有分号 7 月前 |
![]() |
Bin4ry · 子文件夹中的应用程序设置 7 月前 |