在C#中,使用var的推断变量如何在内存和生命周期方面表现出来?

Joe*_*ton 3 c# memory-management type-inference

好吧,我一直在阅读我在var上找到的所有东西,我很确定我已经掌握了他们的基本行为和类型推断.我一直是显式类型的主要支持者,所以var在我阅读代码时让我有点前卫.所以我对它的内存使用情况以及在变量的内存生命周期过程中用var声明的变量的行为有几个问题.

由于var是对显式或匿名类型的推断,因此将其内存分配在相应的类型的相同位置,或者在堆上普遍创建var,并将其作为对象进行访问.举个例子:

int i = 5;  // puts this on the stack
var i = 5;  // does this also go on the stack?
Run Code Online (Sandbox Code Playgroud)

声明的var在初始化后是否具有常量类型,或者也可以进行调整?我问这个,因为我不能指定此文档中找到,我只是读的东西在这太问题@Eric利珀特:

变量是其内容发生变化的存储位置

测试了以下代码后,即使在IDE级别,我也看到了隐式转换异常.我目前没有LINQ的经验来对匿名类型进行类似的测试.他们是否遵循同样的行为?IDE是否会在设计时识别出类型不匹配,或者此类代码是否会收到运行时异常?

var i = 5;    // Initializes as int, value is 5
i = "Steve";  // Type casting error
Run Code Online (Sandbox Code Playgroud)

最后,是否有一种情况你可以想到你在设计时可能知道哪种类型但是无论如何都要谨慎使用var?我问,因为我已经看过人们这样做的代码示例,而且从我读过的内容来看,它只是懒惰编码.

编辑:我意识到有很多文章在讨论这个话题,但我没有找到任何具体回答这些问题的文章(虽然有些暗示某种方式).我很乐意阅读您认为与这些主题相关的任何文档,请发布链接.

Ada*_*son 17

var是C#编译器中的100%语法糖.生成实际IL时,将明确定义类型.var-declared变量与其明确定义的对应变量的行为没有任何不同.您所看到的信息缺乏来自于var比您假设的更简单的事实.这两行之间几乎没有区别:

var i = 10;
int j = 10;
Run Code Online (Sandbox Code Playgroud)

(除了你看到的话其实varint当然,它们在功能上是完全一致).

  • @Adam:在编译时无法在方法的返回类型中直接公开匿名类型这一事实与实例的生命周期没有任何关系!方法可以自由返回对象,该对象可以是匿名类型的实例. (3认同)
  • 或者,您可以通过在lambda中捕获匿名类型的本地变量,然后传递委托来延长匿名类型实例的生命周期.这样你就可以有效地创建一个匿名类型的字段,因为提升的局部变量被实现为字段. (2认同)

Ben*_*son 9

var变量是由编译器推测的,它们实际上只是语法糖,它们之间没有区别:

var i =0;
Run Code Online (Sandbox Code Playgroud)

int i = 0;
Run Code Online (Sandbox Code Playgroud)

在编译的代码中.

添加它们是为了允许匿名类型,例如

var MyVar = new { prop1="A string", prop2=5};
Run Code Online (Sandbox Code Playgroud)

是var vararables在编译时识别类型不匹配,编译器在编译时动态地为它们创建一个类.例如以下不会编译:

var MyVar = new { prop1="A string", prop2=5};
MyVar = "Fred";
Run Code Online (Sandbox Code Playgroud)