我有以下代码:
List<IMessage> messageList = new List<IMessage>();
foreach(var msg in messageList)
{
if(msg != null)
{
}
}
如何针对var
检查null
msg ?是什么告诉编译器var
是IMessage
而不是int
或其他一些不可空的类型?
如果您查看MSDN处的示例,它们会给出隐式类型变量的初始值(声明变为显式)。在我的情况下,我甚至没有给它一个值,但编译器没有问题。编译器如何知道msg
可以为空?
答案 0 :(得分:4)
编译器知道msg
可以为空,因为它是静态类型的。静态类型为IMessage
,即使您没有命名它。
编译器将IMessage
替换为var
的原因是它出现在foreach (var
identifier
in
{ {1}} collection
而)
是实现collection
的类型的表达式。
IEnumerable<IMessage>
的每个外观都会静态替换某些类型。 (它可能是var
,但dynamic
不是默认值,它只能在静态类型推断规则下推断时才适用)如果静态类型推断规则找不到要替换的唯一类型,则不允许使用dynamic
。
答案 1 :(得分:1)
var
是一个非常误导性的关键字。
var
声明一个具有特定数据类型的变量,而不告诉程序员该类型是什么。
您实际声明的是
foreach (IMessage msg in messageList)
但你必须自己解决这个问题。
答案 2 :(得分:0)
编译器会为您推断出类型。在基本层面上,当你说:
var x = "foo";
编译器发现表达式的右侧是string
并指定了x
类型。
当编译器遇到foreach
语句时,它没有什么不同。它确定IEnumerable
类型(您的案例中为IEnumerable<IMessage>
)并为msg
类型IMessage
分配。
答案 3 :(得分:0)
在您的示例中,messageList
的类型为List<IMessage>
,因此,当您执行
foreach (var m in messageList)
C#自动知道期望的项目类型(列表中包含的项目,在此示例中为IMessage
个对象),并推断var将在编译期间转换为IMessage
。
var
关键字只是语法糖,它实际上不是一种类型。它只会让你的生活更轻松(你不必写出实际的类型)
答案 4 :(得分:0)
public static void main(String[] args) throws UnknownHostException {
SpringApplication app = new SpringApplication(App.class);
SimpleCommandLinePropertySource source = new SimpleCommandLinePropertySource(args);
if (!source.containsProperty("spring.profiles.active") &&
!System.getenv().containsKey("SPRING_PROFILES_ACTIVE")) {
app.setAdditionalProfiles("production");
}
...
}
的类型在编译时始终 。任何无法从语法推断出类型的情况都是编译时错误。
在这种情况下,您正在迭代var
的类型集合,因此编译器知道迭代变量的类型为IMessage
,因此可以为空。