我是一名PHP网络程序员,正在学习C#。
我想知道为什么在创建变量时,C#要求我指定数据类型。
Class classInstance = new Class();
为什么在创建类实例之前需要了解其数据类型?
我是一名PHP网络程序员,正在学习C#。
我想知道为什么在创建变量时,C#要求我指定数据类型。
Class classInstance = new Class();
为什么在创建类实例之前需要了解其数据类型?
正如其他人所说,C#是静态/强类型的。但我更多地理解你的问题是:“为什么你希望C#像这样是静态/强类型的?这有什么优势胜过动态语言?”
考虑到这一点,有很多好的理由:
可读性/可维护性 现在你为将来阅读它的开发人员提供了更多关于代码应该如何工作的信息。你添加了特定变量意图持有某种值的信息,这有助于程序员推理出变量的目的。
这可能是为什么例如微软的风格指南建议VB6程序员在变量名前添加类型前缀,但VB.Net程序员不必这样做。
性能 这是最弱的原因,因为后期绑定/鸭子类型可能会更慢。最终,一个变量引用以某种特定方式结构化的内存。没有强类型,程序将不得不在运行时进行额外的类型验证或转换,因为您使用的内存在物理上是以一种方式结构化的,而在逻辑上则以另一种方式结构化。
我不确定是否应该包括此点,因为最终你经常在强类型的语言中进行这些转换。只是强类型的语言将转换的确切时间和程度留给程序员,并且除非必须进行额外的工作,否则不会执行任何额外的工作。它还允许程序员强制使用更有利的数据类型。但这些确实是程序员的属性,而不是平台的属性。
这本身可能是一个薄弱的理由来省略该点,但是优秀的动态语言通常会比程序员做出更好的选择。这意味着动态语言可以帮助许多程序员编写更快的程序。尽管如此,对于优秀的程序员而言,强类型语言具有更快的潜力。
或者,您可能只是想知道为什么在同一行上对于相同的变量需要两次指定类名?答案有两个方面:
var
关键字代替类型名称。以这种方式创建的变量仍然是静态类型,但是类型现在由编译器推断出来。这只是语言设计的一部分。C# 是一种 C 风格的语言,遵循在左侧放置类型的模式。
在 C# 3.0 及以上版本中,您可以使用本地类型推断来解决许多情况。
var variable = new SomeClass();
但与此同时,你也可以认为你在左侧仍然声明了一个类型。只是你希望编译器为你选择它。
编辑
请将此内容放在原始问题的上下文中阅读其中一个主要原因是,只要左侧赋值的类型是右侧类型的父类型(或者实现了该类型的接口),就可以指定不同的类型。
例如,给定以下类型:
class Foo { }
class Bar : Foo { }
interface IBaz { }
class Baz : IBaz { }
C# 允许你这样做:
Foo f = new Bar();
IBaz b = new Baz();
大多数情况下,编译器可以从赋值语句中推断出变量的类型(就像使用var
关键字一样),但由于我上面所示的原因,它并没有这样做。
编辑:作为一种秩序点 - 虽然C#是强类型语言,但重要的区别(就这个讨论而言)是它也是一种静态类型语言。换句话说,C#编译器在编译时进行静态类型检查。
XNamespace ns = "http://url.com";
- Olivier Jacot-Descombes最终,这是因为Anders Hejlsberg这样说了...
您需要在前面加上[class name],因为有很多情况下第一个[class name]与第二个不同,例如:
IMyCoolInterface obj = new MyInterfaceImplementer();
MyBaseType obj2 = new MySubTypeOfBaseType();
等等。如果你不想明确指定类型,你也可以使用单词“var”。
为什么我们需要在创建类实例之前知道数据类型?
其实不需要!从右到左阅读。你先创建变量,然后将其存储在类型安全的变量中,以便稍后使用时知道该变量的类型。
考虑以下代码片段,如果直到运行时才收到错误信息,那将是一场噩梦。
void FunctionCalledVeryUnfrequently()
{
ClassA a = new ClassA();
ClassB b = new ClassB();
ClassA a2 = new ClassB(); //COMPILER ERROR(thank god)
//100 lines of code
DoStuffWithA(a);
DoStuffWithA(b); //COMPILER ERROR(thank god)
DoStuffWithA(a2);
}
当你想用数字或字符串替换 new Class() 时,语法会更加合理。下面的示例可能有点啰嗦,但可以帮助理解为什么它被设计成这样。
string s = "abc";
string s2 = new string(new char[]{'a', 'b', 'c'});
//Does exactly the same thing
DoStuffWithAString("abc");
DoStuffWithAString(new string(new char[]{'a', 'b', 'c'}));
//Does exactly the same thing
正如其他人所指出的,C#是一种强类型、静态类型的语言。
通过提前声明你要创建的类型,当你尝试分配非法值时,编译时会发出警告。通过提前声明方法中接受的参数类型,当你不小心将无意义的内容传递到一个不期望它的方法中时,也会收到同样的编译时警告。这消除了你的某些偏执行为的开销。
最后,而且非常好的是,C#(以及许多其他语言)没有像PHP那样荒谬的“将任何东西转换为任何东西,即使它毫无意义”的思想,这实际上比帮助你更容易被绊倒。
int a = "fred"; // Not allowed. Cannot implicitly convert 'string' to 'int'
C# 是一种强类型语言,类似于 C++ 或 Java。因此,它需要知道变量的类型。在C# 3.0中可以通过 var 关键字轻微地模糊这个问题。这可以让编译器推断出类型。
var classInstance = new Class();
来创建类的实例。FYI(供参考)。 - Jeff Atwood