为什么C#可以检查'var'是否为空?

时间:2016-06-08 13:46:12

标签: c# null nullable var

我有以下代码:

List<IMessage> messageList = new List<IMessage>();

foreach(var msg in messageList)
{
    if(msg != null)
    {

    }
}

如何针对var检查null msg ?是什么告诉编译器varIMessage而不是int或其他一些不可空的类型?

如果您查看MSDN处的示例,它们会给出隐式类型变量的初始值(声明变为显式)。在我的情况下,我甚至没有给它一个值,但编译器没有问题。编译器如何知道msg可以为空?

5 个答案:

答案 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,因此可以为空。