我有以下代码:
List<IMessage> messageList = new List<IMessage>();
foreach(var msg in messageList)
{
if(msg != null)
{
}
}
如何根据null
检查var
味精?什么告诉编译器var
是一个IMessage
,而不是一个int
或一些不可为空的其他类型的类型?
如果您查看 MSDN 上的示例,它们会为隐式类型变量提供初始值(声明变得显式)。就我而言,我什至没有给它一个值,但编译器对它没有问题。编译器如何知道msg
可为空?
知道msg
可为空,因为它是静态类型的。 静态类型是 IMessage
,即使您没有命名它。
编译器将IMessage
替换为var
的原因是它出现在foreach (var
identifier
in
collection
)
中,并且collection
是实现IEnumerable<IMessage>
的类型的表达式。
var
的每次出现都会静态替换某种类型。 (这可能是dynamic
,但dynamic
不是默认值,它只能在静态类型推断规则下推断时适用) 如果静态类型推断规则找不到要替换的唯一类型,则不允许使用 var
。
var
是一个非常具有误导性的关键字。
var
声明了一个具有特定数据类型的变量,而不告诉程序员该类型是什么。
您实际声明的是
foreach (IMessage msg in messageList)
但你必须自己解决这个问题。
编译器将为您推断类型。在基本层面上,当你说:
var x = "foo";
编译器看到表达式的右侧是string
,并x
该类型进行分配。
当编译器遇到 foreach
语句时,情况也没有什么不同。它确定IEnumerable
类型(在您的情况下IEnumerable<IMessage>
)并msg
分配类型IMessage
。
在您的示例中,您的messageList
属于 List<IMessage>
类型,因此,当您这样做时
foreach (var m in messageList)
C# 会自动知道预期需要什么类型的项(列表中包含的项,在此示例中为对象IMessage
项),并推断 var 将在编译时转换为 IMessage
。
var
关键字只是句法糖,它实际上不是一种类型。它只是让你的生活更轻松(你不必写实际的类型)
var
的类型在编译时总是已知的。无法从语法推断出类型的任何情况都是编译时错误。
在本例中,您正在迭代 IMessage
的类型化集合,因此编译器知道迭代变量的类型为 IMessage
,因此可为 null。