为什么 C# 是静态类型的?
我是一名 PHP Web 程序员,正在尝试学习 C#。
我想知道为什么C#要求我在创建变量时指定数据类型。
Class classInstance = new Class();
为什么我们需要在类实例之前知道数据类型?
I am a PHP web programmer who is trying to learn C#.
I would like to know why C# requires me to specify the data type when creating a variable.
Class classInstance = new Class();
Why do we need to know the data type before a class instance?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(17)
这就是语言的设计方式。 C# 是一种 C 风格语言,遵循类型位于左侧的模式。
在 C# 3.0 及更高版本中,在许多情况下您可以通过本地类型推断来解决这个问题。
但同时您也可能会争辩说您仍在 LHS 上声明类型。 只是您希望编译器为您选择它。
编辑
请在用户原始问题的上下文中阅读此内容
我想评论这个帖子中的其他几个答案。 很多人都给出“C# 是静态类型”作为答案。 虽然该陈述是正确的(C# 是静态类型的),但它几乎与问题完全无关。 静态类型不需要类型名称位于变量名称的左侧。 当然它可以提供帮助,但这是语言设计者的选择,而不是静态类型语言的必要功能。
通过考虑其他静态类型语言(例如 F#),可以轻松证明这些。 F# 中的类型出现在变量名的右侧,并且通常可以完全省略。 还有几个反例。 例如,PowerShell 非常动态,并将其所有类型(如果包含)放在左侧。
It's simply how the language was designed. C# is a C-style language and follows in the pattern of having types on the left.
In C# 3.0 and up you can kind of get around this in many cases with local type inference.
But at the same time you could also argue that you are still declaring a type on the LHS. Just that you want the compiler to pick it for you.
EDIT
Please read this in the context of the users original question
I wanted to comment on several other answers in this thread. A lot of people are giving "C# is statically type" as an answer. While the statement is true (C# is statically typed), it is almost completely unrelated to the question. Static typing does not necessitate a type name being to the left of the variable name. Sure it can help but that is a language designer choice not a necessary feature of static typed languages.
These is easily provable by considering other statically typed languages such as F#. Types in F# appear on the right of a variable name and very often can be altogether ommitted. There are also several counter examples. PowerShell for instance is extremely dynamic and puts all of its type, if included, on the left.
主要原因之一是,只要赋值左侧的类型是左侧类型的父类型(或在该类型上实现的接口),您就可以指定不同的类型。
例如,给定以下类型:
C# 允许您执行此操作:
是的,在大多数情况下,编译器可以从赋值中推断出变量的类型(例如
var< /code>
关键字),但事实并非如此,原因如我上面所示。
编辑:作为一个程序问题 - 虽然 C# 是强类型的,但重要的区别(就本次讨论而言)是它实际上也是一个 >静态类型语言。 换句话说,C# 编译器在编译时进行静态类型检查。
One of the main reasons is that you can specify different types as long as the type on the left hand side of the assignment is a parent type of the type on the left (or an interface that is implemented on that type).
For example given the following types:
C# allows you to do this:
Yes, in most cases the compiler could infer the type of the variable from the assignment (like with the
var
keyword) but it doesn't for the reason I have shown above.Edit: As a point of order - while C# is strongly-typed the important distinction (as far as this discussion is concerned) is that it is in fact also a statically-typed language. In other words the C# compiler does static type checking at compilation time.
C# 是一种静态类型,强类型语言,例如 C 或 C++。 在这些语言中,所有变量都必须声明为特定类型。
C# is a statically-typed, strongly-typed language like C or C++. In these languages all variables must be declared to be of a specific type.
最终因为安德斯·海尔斯伯格这么说......
Ultimately because Anders Hejlsberg said so...
您需要在前面添加[类名],因为在很多情况下第一个[类名]与第二个不同,例如:
等。如果您不想指定类型,也可以使用“var”一词明确地。
You need [class name] in front because there are many situations in which the first [class name] is different from the second, like:
etc. You can also use the word 'var' if you don't want to specify the type explicitely.
你不! 从右向左读取。您创建变量,然后将其存储在类型安全变量中,以便您知道该变量的类型以供以后使用。
考虑下面的代码片段,如果直到运行时才收到错误,那么调试将是一场噩梦。
当您认为可以用数字或字符串替换 new Class() 时,语法会更有意义。 以下示例可能有点冗长,但可能有助于理解为什么要这样设计。
You don't! Read from right to left. You create the variable and then you store it in a type safe variable so you know what type that variable is for later use.
Consider the following snippet, it would be a nightmare to debug if you didn't receive the errors until runtime.
When you'r thinking you can replace the new Class() with a number or a string and the syntax will make much more sense. The following example might be a bit verbose but might help to understand why it's designed the way it is.
正如其他人指出的那样,C# 是一种强静态类型语言。
通过预先声明您要创建的类型,当您尝试分配非法值时,您将收到编译时警告。 通过预先声明您在方法中接受的参数类型,当您不小心将无意义的内容传递到不期望的方法时,您会收到相同的编译时警告。 它为您消除了一些偏执的开销。
最后,相当好的一点是,C#(以及许多其他语言)不像 PHP 那样具有荒谬的“将任何内容转换为任何内容,即使它没有意义”的心态,坦率地说,这可能会让您更多次陷入困境比它有帮助。
C#, as others have pointed out, is a strongly, statically-typed language.
By stating up front what the type you're intending to create is, you'll receive compile-time warnings when you try to assign an illegal value. By stating up front what type of parameters you accept in methods, you receive those same compile-time warnings when you accidentally pass nonsense into a method that isn't expecting it. It removes the overhead of some paranoia on your behalf.
Finally, and rather nicely, C# (and many other languages) doesn't have the same ridiculous, "convert anything to anything, even when it doesn't make sense" mentality that PHP does, which quite frankly can trip you up more times than it helps.
c# 是一种强类型语言,如 c++ 或 java。 因此它需要知道变量的类型。 你可以在 c# 3.0 中通过 var 关键字来修改它。 这可以让编译器推断出类型。
c# is a strongly-typed language, like c++ or java. Therefore it needs to know the type of the variable. you can fudge it a bit in c# 3.0 via the var keyword. That lets the compiler infer the type.
这就是强类型语言和弱类型语言之间的区别。 C#(以及 C、C++、Java 等最强大的语言)是强类型的,因此您必须声明变量类型。
That's the difference between a strongly typed and weakly typed language. C# (and C, C++, Java, most more powerful languages) are strongly typed so you must declare the variable type.
当我们定义变量来保存数据时,我们必须指定这些变量将保存的数据类型。 然后编译器检查我们对数据所做的事情是否对其有意义,即遵循规则。 例如,我们不能将文本存储在数字中 - 编译器将不允许这样做。
变量 a 是 int 类型,为它分配值“fred”(文本字符串)违反了规则 - 编译器无法对此字符串进行任何类型的转换。
When we define variables to hold data we have to specify the type of data that those variables will hold. The compiler then checks that what we are doing with the data makes sense to it, i.e. follows the rules. We can't for example store text in a number - the compiler will not allow it.
The variable a is of type int, and assigning it the value "fred" which is a text string breaks the rules- the compiler is unable to do any kind of conversion of this string.
在 C# 3.0 中,您可以使用“var”关键字 - 这使用静态类型推断来确定编译时变量的类型,
从那时起,变量“foo”将是“ClassName”类型。
In C# 3.0, you can use the 'var' keyword - this uses static type inference to work out what the type of the variable is at compile time
variable 'foo' will be of type 'ClassName' from then on.
没有提到的一件事是 C# 是一种符合 CLS(公共语言规范)的语言。 这是 .NET 语言必须遵守的一组规则,以便与其他 .NET 语言互操作。
所以实际上 C# 只是遵守这些规则。 引用这篇 MSDN 文章:
CLS 的一部分是 CTS,即通用类型系统。
如果这对您来说还不够,那么 .NET 中还有很多缩写词,例如 CLI、ILasm/MSIL、CLR、BCL、FCL、
One things that hasn't been mentioned is that C# is a CLS (Common Language Specification) compliant language. This is a set of rules that a .NET language has to adhere to in order to be interopable with other .NET languages.
So really C# is just keeping to these rules. To quote this MSDN article:
Part of the CLS is the CTS the Common Type System.
If that's not enough acronyms for you then there's a tonne more in .NET such as CLI, ILasm/MSIL, CLR, BCL, FCL,
因为 C# 是强类型语言
Because C# is a strongly typed language
静态类型还允许编译器进行更好的优化,并跳过某些步骤。 以重载为例,其中您有多个具有相同名称的方法或运算符,仅参数不同。 使用动态语言,运行时需要对每个版本进行评分,以确定哪个是最佳匹配。 使用这样的静态语言,最终代码只需直接指向适当的重载即可。
静态类型还有助于代码维护和重构。 我最喜欢的例子是许多高端 IDE 的重命名功能。 借助静态类型,IDE 可以准确地找到代码中标识符的每次出现,并完整保留具有相同名称的不相关标识符。
我没有注意到它是否被提及,但 C# 4.0 通过
dynamic
关键字引入了动态检查。 尽管我确信您会在不必要时避免使用它。Static typing also allows the compiler to make better optimizations, and skip certain steps. Take overloading for example, where you have multiple methods or operators with the same name differing only by their arguments. With a dynamic language, the runtime would need to grade each version in order to determine which is the best match. With a static language like this, the final code simply points directly to the appropriate overload.
Static typing also aids in code maintenance and refactoring. My favorite example being the Rename feature of many higher-end IDEs. Thanks to static typing, the IDE can find with certainty every occurrence of the identifier in your code, and leave unrelated identifiers with the same name intact.
I didn't notice if it were mentioned yet or not, but C# 4.0 introduces dynamic checking VIA the
dynamic
keyword. Though I'm sure you'd want to avoid it when it's not necessary.我认为大多数答案没有提到的一件事是,C# 最初的含义和设计是“托管”、“安全”语言等,其中许多目标是通过静态/编译时可验证性。 明确地了解变量数据类型使得这个问题更容易解决。 这意味着人们可以对可能的错误/不良行为进行多次自动评估(C# 编译器,而不是 JIT),而无需执行。
这种可验证性作为副作用还为您提供了更好的可读性、开发工具、稳定性等,因为如果自动化算法可以更好地理解代码在实际运行时会做什么,那么您也可以:)
I think one thing that most answers haven't referenced is the fact that C# was originally meant and designed as "managed", "safe" language among other things and a lot of those goals are arrived at via static / compile time verifiability. Knowing the variable datatype explicitly makes this problem MUCH easier to solve. Meaning that one can make several automated assessments (C# compiler, not JIT) about possible errors / undesirable behavior without ever allowing execution.
That verifiability as a side effect also gives you better readability, dev tools, stability etc. because if an automated algorithm can understand better what the code will do when it actually runs, so can you :)
静态类型意味着编译器可以在编译时而不是运行时执行某种检查。 每个变量都是静态类型中的特定类型或强类型。 C# 是强绝对强类型的。
Statically typed means that Compiler can perform some sort of checks at Compile time not at run time. Every variable is of particular or strong type in Static type. C# is strongly definitely strongly typed.
正如其他人所说,C# 是静态/强类型的。 但我更多地认为你的问题是“为什么你希望 C# 成为这样的静态/强类型?与动态语言相比,它有什么优势?”
考虑到这一点,有很多充分的理由:
可读性/可维护性 您现在向未来阅读该代码的开发人员提供有关代码应如何工作的更多信息。 您添加特定变量旨在保存某种值的信息,这可以帮助程序员推断该变量的用途。
这可能就是为什么,例如,Microsoft 的风格指南建议 VB6 程序员在变量名中添加类型前缀,但 VB.Net 程序员则不然。
性能这是最弱的原因,但后期绑定/鸭子打字可能会更慢。 最后,变量是指以某种特定方式构造的内存。 如果没有强类型,程序将不得不在运行时在幕后进行额外的类型验证或转换,因为您使用的内存在物理上以一种方式构造,就像在逻辑上以另一种方式构造一样。
我犹豫是否要包括这一点,因为最终您通常还必须使用强类型语言进行这些转换。 只是强类型语言将转换的确切时机和范围留给了程序员,除非需要做,否则不做额外的工作。 它还允许程序员强制使用更有利的数据类型。 但这些确实是程序员的属性,而不是平台的属性。
这本身就是忽略这一点的弱理由,除非好的动态语言通常会比程序员做出更好的选择。 这意味着动态语言可以帮助许多程序员编写更快的程序。 尽管如此,对于优秀程序员来说,强类型语言有可能更快。
或者您可能只是想知道为什么必须为同一行上的同一变量指定两次类名? 答案有两个:
var
关键字代替类型名称。 以这种方式创建的变量仍然是静态类型的,但编译器现在可以为您推断出类型。As others have said, C# is static/strongly-typed. But I take your question more to be "Why would you want C# to be static/strongly-typed like this? What advantages does this have over dynamic languages?"
With that in mind, there are lots of good reasons:
Readability/Maintainability You are now providing more information about how the code is supposed to work to future developers who read it. You add information that a specific variable is intended to hold a certain kind of value, and that helps programmers reason about what the purpose of that variable is.
This is probably why, for example, Microsoft's style guidelines recommended that VB6 programmers put a type prefix with variable names, but that VB.Net programmers do not.
Performance This is the weakest reason, but late-binding/duck typing can be slower. In the end, a variable refers to memory that is structured in some specific way. Without strong types, the program will have to do extra type verification or conversion behind the scenes at runtime as you use memory that is structured one way physically as if it were structured in another way logically.
I hesitate to include this point, because ultimately you often have to do those conversions in a strongly typed language as well. It's just that the strongly typed language leaves the exact timing and extent of the conversion to the programmer, and does no extra work unless it needs to be done. It also allows the programmer to force a more advantageous data type. But these really are attributes of the programmer, rather than the platform.
That would itself be a weak reason to omit the point, except that a good dynamic language will often make better choices than the programmer. This means a dynamic language can help many programmers write faster programs. Still, for good programmers, strongly-typed languages have the potential to be faster.
Or perhaps you were just wondering why you have to specify the class name twice for the same variable on the same line? The answer is two-fold:
var
keyword instead of the type name in many cases. Variables created this way are still statically typed, but the type is now inferred for you by the compiler.