在学习C#时,我想到了这个问题。 void
和var
之间有什么区别?
以下是我想分享的两个例子:
void * voidInt = (void *) 7;
void * voidChar = (void *) 'F';
void * voidCharArray = (void *) "AbcString";
这是var
的例子:
var varInt = 7;
var varChar = 'F';
var varCharArray = "AbcString";
void
是匿名数据类型吗? var
和void
之间的差异?有人可以帮助我清除这种情况吗?
答案 0 :(得分:32)
这里的其他答案都相当不错,但我认为他们没有清楚地了解基本面。这是你困惑的基本原则,所以让我们解决这些问题。
所以voidInt
,voidChar
,voidCharArray
,varInt
,varChar
和varCharArray
都是变量,它们都有类型与它们相关联。每个变量都可以分配该类型的值,或生成该类型的值,具体取决于是否正在写入或读取变量。
好的,现在指针是什么?
void *
类型是一种特殊的指针类型。T*
的指针可以取消引用以生成类型为T
的变量。 T*
不得为void*
。void*
。 void*
值都可以显式转换为任何指针类型值。 C#中的var
是什么?
var
是一种"语法糖"告诉编译器从initialzier推导出变量的类型,而不是要求它被写出来。什么是"匿名类型"在C#?
现在我们可以看一下你的程序,看看每行的作用。
void * voidInt = (void *) 7;
voidInt
是void*
类型的变量。分配给它的值是整数7到指针的转换,这几乎可以肯定是任何现代操作系统上的垃圾指针。这段代码基本上是荒谬的。
更明智的代码是:
int myInt = 7;
int* intPtr = &myInt;
void* voidInt = intPtr;
这意味着myInt
是一个保存值7
的变量,intPtr
是一个保存指针的变量;当该指针被解除引用时,它产生变量myInt
。 voidInt
是一个包含任何指针的变量,从intPtr
读取的值是一个指针。所以现在voidInt
和intPtr
都有一个指向变量myInt
的指针。
void * voidChar = (void *) 'F';
这里也是一样的。字符F
被视为数字并转换为指针值,该值存储在变量中。这不明智。明智的代码将是这样的:
char myChar = 'F';
void *voidChar = &myChar;
但这很有道理:
void * voidCharArray = (void *) "AbcString";
C ++中的字符串文字可转换为char*
,它是指向第一个字符的存储的指针,该指针可转换为void*
。
这个怎么样?
var varInt = 7;
var varChar = 'F';
var varCharArray = "AbcString";
这只是一种令人愉快的写作方式
int varInt = 7;
char varChar = 'F';
string varCharArray = "AbcString";
每个变量都有给定的类型,每个赋值都在变量中存储该类型的值。
匿名类型怎么样?
var anon = new { X = 123, Y = 456 };
这使得匿名类型的变量,其中匿名类型具有两个属性X和Y,类型int
。该类型没有名称,因此无法在声明中写出类型,因此必须使用var
。
这里的关键是要确保你掌握基础:指针是值,它们可能是解除引用,这样做会产生一个变量。由于指针是值,它们本身可以存储在指针类型的变量中。这几乎与var
无关,这在C#中是一种令人愉快的方式,使编译器能够确定变量应该具有的类型。
答案 1 :(得分:18)
void
和var
并没有任何共同之处:
void(由C和C ++中的指针变量使用)表示未指定(非确定)类型。在托管C#中不允许void*
(尽管非常弱的类型,例如object
引用可能是近似的)。通常,需要重新构建void*
类型才能使用。
但是,方法/函数中的void
返回类型意味着相同
用两种语言表示没有返回值(如Scala中的Unit
)
var
定义了implicitly typed variable - 变量仍然具有强类型,但实际类型是在编译时从右侧推断的。e.g。
var v1 = "Foo"; // v1 is a string, because it is inferred from the right hand side
var v2 = XDocument.Parse(@"c:\temp\foo.xml"); // v2 is the return type of the function
使用匿名类型时经常需要 var
- 这可能是您在var
和匿名类型之间建立连接的地方:
var v3 = new { Name = "Foo", Value = 123}; // v3 is strongly typed, anonymous class.
var
对于将变量赋值给LINQ表达式的返回值特别有用,其中类型可能非常复杂:
var v3 = db.Persons
.Join(db.Cities, p => p.CityId, c => c.Id, (p, c) => new {Person = p, City = c})
.GroupBy(pc => pc.City.Name);
*实际上,这并不完全正确,您可以在C#中使用void * unsafe
修改强>
另外值得一提的是,从C#6开始,隐式var
输入只能用于局部变量,即C#不支持隐式输入方法返回类型(与Scala等函数式语言不同) ,大多数情况下编译器也可以推断出方法的返回类型。)
答案 2 :(得分:7)
void*
相当于void*
。可以将任何数据指针类型分配给void*
。object
(松散地)是相应的概念。可以为其分配任何类/接口/结构实例。var
的等价物是auto
。当用于声明和初始化局部变量时,它可以作为分配给该变量的表达式的类型(如果可能的话)。答案 3 :(得分:3)
您可以使用c ++ void pointer:
执行此操作void * val = (void *) 7;
val = (void *) "Abcd";
但你不能用c#var:
这样做var val = 7;
val = "abcd";
这会引发错误。
如果您希望实现void *
的类似行为,可以使用dynamic
。
dynamic val = (dynamic) 7;
val = (dynamic) "ABC";
使用var
时,变量的实际类型在编译时确定。但是,当使用dynamic
时,变量的实际类型是在运行时确定的。