为什么C#是静态输入的?

时间:2009-05-13 17:05:28

标签: c# static-typing

我是一名试图学习C#的PHP网络程序员。

我想知道为什么C#要求我在创建变量时指定数据类型。

Class classInstance = new Class();

为什么我们需要在类实例之前知道数据类型?

17 个答案:

答案 0 :(得分:106)

正如其他人所说,C#是静态/强类型的。但是我更多地提出你的问题是“为什么你希望 C#像这样静态/强类型?这对动态语言有什么优势?”

考虑到这一点,有很多充分的理由:

  • 稳定性编码器会自动捕获某些类型的错误,然后代码才能使其接近生产。
  • 可读性/可维护性您现在提供有关代码如何适用于未来开发人员的更多信息。您添加特定变量旨在保存某种值的信息,这有助于程序员推断该变量的用途。

    这可能就是为什么,例如,Microsoft的样式指南建议VB6程序员使用变量名称来设置类型前缀,但VB.Net程序员不会这样做。

  • 性能这是最薄弱的原因,但后期绑定/鸭子打字可能会变慢。最后,变量指的是以某种特定方式构造的内存。如果没有强类型,程序将不得不在运行时在幕后进行额外的类型验证或转换,因为您使用的是一种物理结构的内存,就像它在逻辑上以另一种方式构造一样。

    我毫不犹豫地提到这一点,因为最终你经常需要用强类型语言进行转换。只是强类型语言将转换的确切时间和范围留给程序员,除非需要完成,否则不需要额外的工作。它还允许程序员强制使用更有利的数据类型。但这些确实是程序员的属性,而不是平台。

    除了优秀的动态语言通常比程序员做出更好的选择之外,这本身就是忽略这一点的一个弱理由。这意味着动态语言可以帮助许多程序员编写更快的程序。不过,对于好的程序员来说,强类型语言的潜力更快。

  • 更好的开发工具如果您的IDE知道变量的类型,它可以为您提供有关变量可以执行哪些操作的额外帮助。如果必须为您推断类型,IDE就更难做到这一点。如果您从IDE获得API的细节更多帮助,那么作为开发人员,您将能够了解更大,更丰富的API,并更快地实现目标。

或许您只是想知道为什么必须在同一行上为同一个变量指定两次类名?答案是双重的:

  1. 通常你不这样做。在C#3.0及更高版本中,在许多情况下,您可以使用var关键字而不是类型名称。以这种方式创建的变量仍然是静态类型的,但编译器现在为您提供推断类型。
  2. 由于继承和接口,有时左侧的类型与右侧的类型不匹配。

答案 1 :(得分:23)

这就是语言的设计方式。 C#是一种C风格的语言,它遵循左侧类型的模式。

在C#3.0及更高版本中,你可以通过本地类型推断在很多情况下解决这个问题。

var variable = new SomeClass();

但与此同时,您也可以争辩说您仍在宣布LHS的类型。只是你希望编译器为你挑选它。

编辑

请在用户原始问题的上下文中阅读

  

为什么我们在变量名之前需要[类名]?

我想在这个帖子中评论其他几个答案。很多人都把“C#静态类型”作为答案。虽然声明是真的(C#是静态类型的),但它几乎完全与问题无关。静态类型不需要在变量名左侧使用类型名称。当然它可以提供帮助,但这是语言设计者的选择,而不是静态类型语言的必要功能。

通过考虑其他静态类型语言(如F#),可以很容易地证明这些。 F#中的类型出现在变量名的右侧,并且通常可以完全省略。还有几个反例。例如,PowerShell是非常动态的,如果包含它,则将其所有类型放在左侧。

答案 2 :(得分:21)

主要原因之一是您可以指定不同的类型,只要分配左侧的类型是左侧类型的父类型(或在该类型上实现的接口)。

例如,给出以下类型:

class Foo { }
class Bar : Foo { }
interface IBaz { }
class Baz : IBaz { }

C#允许您这样做:

Foo f = new Bar();
IBaz b = new Baz();

是的,在大多数情况下,编译器可以从分配中推断变量的类型(例如 var 关键字),但它不是由于我上面所示的原因。

编辑:作为程序问题 - 虽然C#强类型,但重要的区别(就此讨论而言)是它实际上也是 静态类型 语言。换句话说,C#编译器在编译时进行静态类型检查。

答案 3 :(得分:16)

C#是一种statically-typedstrongly-typed语言,如C或C ++。在这些语言中,必须将所有变量声明为特定类型。

答案 4 :(得分:9)

最终因为Anders Hejlsberg这么说......

答案 5 :(得分:5)

你需要[班级名称],因为有很多情况下第一个[班级名称]与第二个不同,如:

 IMyCoolInterface obj = new MyInterfaceImplementer();
 MyBaseType obj2 = new MySubTypeOfBaseType();

等。如果您不想明确指定类型,也可以使用“var”一词。

答案 6 :(得分:3)

  

为什么我们需要知道数据类型   之前一个类实例?

你没有! 从右到左阅读。您创建变量然后将其存储在类型安全变量中,以便您知道该变量的类型以供以后使用。

考虑以下代码段,如果在运行时之前没有收到错误,则调试将是一场噩梦。

 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

答案 7 :(得分:2)

正如其他人所指出的那样,C#是一种强烈的,静态类型的语言。

通过预先说明您打算创建的类型,当您尝试分配非法值时,您将收到编译时警告。通过在前面说明您在方法中接受哪种类型的参数,当您意外地将废话传递给不期望它的方法时,您会收到相同的编译时警告。它代表你消除了一些偏执的开销。

最后,而且相当不错,C#(和许多其他语言)没有相同的荒谬,“将任何东西转换成任何东西,即使它没有意义”PHP的心态,坦率地说它可以绊倒你比起帮助的次数多了很多次。

答案 8 :(得分:1)

这是强类型和弱类型语言之间的区别。 C#(和C,C ++,Java,更强大的语言)是强类型的,因此您必须声明变量类型。

答案 9 :(得分:1)

当我们定义变量来保存数据时,我们必须指定这些变量将保存的数据类型。然后编译器检查我们对数据的处理是否有意义,即遵循规则。我们不能将文本存储在数字中 - 编译器不允许它。

int a = "fred"; // Not allowed. Cannot implicitly convert 'string' to 'int' 

变量a的类型为int,并为其赋值“fred”,这是一个文本字符串会破坏规则 - 编译器无法对此字符串进行任何类型的转换。

答案 10 :(得分:1)

在C#3.0中,您可以使用'var'关键字 - 这使用静态类型推断来计算变量在编译时的类型

var foo = new ClassName();

变量'foo'从那时起将是'ClassName'类型。

答案 11 :(得分:1)

c#是一种强类型语言,如c ++或java。因此,它需要知道变量的类型。你可以通过var关键字在c#3.0中稍微捏一下它。这让编译器可以推断出类型。

答案 12 :(得分:1)

因为C#是强类型语言

答案 13 :(得分:1)

未提及的一件事是C#是符合CLS(公共语言规范)的语言。这是一组.NET语言必须遵守的规则,以便与其他.NET语言互操作。

所以C#真的只是遵守这些规则。引用this MSDN article

  

CLS有助于增强和确保   通过定义语言互操作性   开发人员可以使用的一组功能   依靠在广泛的可用   各种语言。 CLS也   建立CLS的要求   合规性;这些可以帮助您确定   您的托管代码是否符合   CLS以及给定的程度   工具支持开发   使用CLS功能的托管代码。

     

如果您的组件仅使用CLS   它所公开的API中的功能   其他代码(包括派生的   类),组件是有保证的   可以通过任何编程访问   支持CLS的语言。   符合CLS的组件   规则并仅使用这些功能   据说包含在CLS中   符合CLS的组件

CLS的一部分是CTS Common Type System

如果这对你来说还不够,那么在.NET中有更多,例如CLI,ILasm / MSIL,CLR,BCL,FCL,

答案 14 :(得分:0)

静态类型还允许编译器进行更好的优化,并跳过某些步骤。以重载为例,你有多个方法或同名的运算符只有它们的参数不同。使用动态语言,运行时需要对每个版本进行分级,以确定哪个是最佳匹配。使用这样的静态语言,最终代码只是直接指向适当的重载。

静态类型还有助于代码维护和重构。我最喜欢的例子是许多高端IDE的重命名功能。由于静态类型,IDE可以确定地找到代码中每次出现的标识符,并保留相同名称的无关标识符。

我没有注意到它是否被提及,但C#4.0引入了动态检查VIA dynamic关键字。虽然我确定你不想在没必要的时候避免它。

答案 15 :(得分:0)

  

为什么C#要求我在创建变量时指定数据类型。

     

为什么我们需要在类实例之前知道数据类型?

我认为大多数答案没有引用的一件事是,C#最初意味着设计为“托管”,“安全”语言等等,其中很多目标都是通过静态/编译时可验证性到达。明确知道变量数据类型会使这个问题更容易解决。意味着可以在不允许执行的情况下对可能的错误/不良行为进行多次自动评估(C#编译器,而不是JIT)。

作为副作用的可验证性还为您提供了更好的可读性,开发工具,稳定性等等,因为如果自动算法能够更好地理解代码在实际运行时将执行的操作,那么您可以:)

答案 16 :(得分:0)

静态类型意味着编译器可以在编译时执行某种检查而不是在运行时。每个变量在Static类型中都是特定的或强类型。 C#绝对是强类型的。