C#是一种强类型语言还是弱类型语言?

4
请问C#是强类型语言还是弱类型语言?请解释一下为什么。
如果我有一个名为concat的函数,可以接受任何对象,那么这是否被认为是弱类型语言?
function concat(Object stuff)
{
   //do something here to stuff
}

9
“Downvoter们是否愿意给出理由,这样@Mrshll187就会知道以后应该避免做什么?” - Abe Miessler
5
@Servy,不是这样的,我希望能够找到更多的信息。您可能会注意到Mrshll187也发表了评论,说他已经谷歌过了,但没有得到很好的结果。如果你在谷歌搜索中没有找到答案,然后来这里寻求帮助似乎是一个相当合理的方法。顺便说一句,我认为像你这样的讽刺性评论会让SO成为一个不那么令人愉快的地方,我们都在这里花时间帮助人们。我知道你可能不在意,但这就是我的两分钱。干杯。 - Abe Miessler
3
“@Mrshll187: 你本来可以在最初的问题中说清楚,而不是让我们去问。” - BoltClock
2
@AbeMiessler 嗯,谷歌搜索这个问题的确切标题会产生几个非常清楚地回答了我的问题。如果OP在理解他看到的结果方面有困难,那么他应该更详细地解释一下他发现了什么,为什么他感到困惑等等。事实上,这个问题明显表明没有进行研究。如果你觉得给出的评论不够详细,那么也许你可以提供更多的细节,或者要求其他人提供更多的细节,而不是假装没有人提供任何评论。 - Servy
2
呃...那不是我上一条评论所指的。 - BoltClock
显示剩余2条评论
6个回答

16

来自 http://ericlippert.com/2012/10/15/is-c-a-strongly-typed-or-a-weakly-typed-language/

C#是强类型语言还是弱类型语言?

是的。

这并没有帮助。

我不怀疑。有趣的是,如果你把问题重述为“并且”问题,答案将是一样的。

什么?你的意思是,C#既是强类型语言又是弱类型语言?

是的,C#是一种既是强类型语言又是弱类型语言的语言。

我困惑了。

我也是。或许你应该告诉我,“强类型”和“弱类型”具体指什么。

嗯,实际上我并不知道我用这些术语时具体指的是什么,所以也许那才是我应该问的问题。一个语言要成为“弱类型”或“强类型”,到底意味着什么?

“弱类型”意味着“这种语言使用了我认为不好的类型验证系统”,而“强类型”则意味着“这种语言使用了我认为好的类型系统”。


3
@Mrshll187 嗯,除了我这个答案之外,其他的答案都陈述了可以证明是错误的内容。鉴于所提出的问题,这里的所有内容都足够正确。当你搜索答案时,该链接也应该会在谷歌中显示出来。 - Servy
维基百科基本上证实,“强类型”和“弱类型”通常没有什么意义,一个用于赞扬语言,另一个用于批评它。那篇文章比大多数文章更具有主观性。 - trysis

11

C#是一种强类型语言。

ECMA-334将C#定义为“C#(发音为“C Sharp”)是一种简单,现代,面向对象和类型安全的编程语言。”

维基百科定义类型安全:

类型安全与强类型之一的许多定义是同义词;但类型安全和动态类型是相互兼容的。

维基百科定义强类型:

在计算机科学和计算机编程中,当类型系统指定了一个或多个限制条件,规定不同数据类型的值可以如何交错使用时,该类型系统被称为具有强类型。弱类型则是其对立面。

或许更好的问题是,如果编译器进行类型检查,则C#是否是一种类型安全的语言,因为似乎没有人能就“强弱类型”的真正含义达成共识。

C#确实有一些类似于动态语言的构造可用,但令人惊讶的是,在编译时这些构造仍然是类型安全的。

从 Visual C#3.0 开始,声明在方法范围内的变量可以具有隐式类型 var。 隐式类型的局部变量是强类型的,就像您自己声明了类型一样,但编译器会确定类型。

http://msdn.microsoft.com/en-us/library/bb383973.aspx

dynamic 关键字基本上是以与 var 不同的方式工作,因为它在运行时而不是在编译时进行评估。

Visual C# 2010 引入了一种新类型,即 dynamic。该类型是静态类型,但 dynamic 类型的对象绕过了静态类型检查。在大多数情况下,它的功能类似于具有 object 类型。在编译时,被标记为 dynamic 的元素被认为支持任何操作。

http://msdn.microsoft.com/en-us/library/dd264736.aspx


为什么要踩这个答案呢?它完全是正确的。如果你选择踩,留下一个评论,这样我就能理解为什么你不喜欢这个答案了。 - Mr. Young
这个论点没有任何“如果/并且/但是”的余地。好吧,“强类型”没有明确的含义,因此无法确定它是否适用于特定的语言。 - Servy
2
我给了你一个赞,但我猜dw是因为你断言“这个论点没有任何的如果/和/但”。 我可以给你一些线索,说明为什么这样说并不是好事: 如果你提出一个论点,而“没有有效的反驳论点”,那么你根本就没有提出一个论点,而是在断言某些事情。 第二:当然有如果和但:请看Gideon的答案,很快就会被接受,如果SO保持其几乎恒定的质量水平。 - Casper Leon Nielsen
1
感谢您的精彩反馈。我已根据反馈调整了我的答案。也许我可以赚回那些分数。 - Mr. Young
@Mr.Young 那么您从这句话中想表达什么?当您使用 dynamic 时,您将删除所有有意义的静态类型,从而在使用时将其关闭。因此,虽然 C# 可以在保持静态类型的情况下使用,但是有许多违反静态类型的方法。其中一种是动态类型,另一种是 unsafe 代码,甚至基本转换也是违反静态类型的最简单、最容易的方式,因此 C# 不是一个完全静态类型的语言。 - Servy
显示剩余5条评论

5

一般而言:C#通常以强类型方式被使用,这意味着一个变量会被声明为一个特定的Type(例如:string、int、用户自定义类型等),且后续不能将其赋值为不同类型的值。

例如:在C#中无法这样做:

int i = 10;
i = "ten";

如下评论所述,C#可以有不同的使用方式。

使用“强类型”让编辑器/编译器提醒您错误,并让编辑器为您提供可能需要的缩小范围的建议。


2
按照这个定义,没有强类型语言是不可能的,因为所有变量几乎总是属于某种类型,比如代表“任何东西”的变体。 - Servy
4
你的意思是像在C#中一样,我可以将一个字符串分配给类型为“object”的变量,然后再将一个“int”分配给它吗? - Servy
1
实际上,即使使用object,C#也是部分强类型的 - 你不能简单地引用变量的属性。例如,你不能设置object i = "ten";然后获取i.Length - ispiro
1
@ispiro 如果你使用 dynamic,就可以这样做。同样,你可以使用强制类型转换来告诉编译器从 i 中的对象获取 Length 属性。事实上,强制类型转换本质上违反了强类型的特性。它的整个目的就是允许你违反编译器的类型系统。 - Servy
尝试这样做:创建一个接受并返回Int的方法。创建一个接受并返回float的方法。使用方法输入从Int方法调用float方法并查看返回结果。发生的情况是Int被隐式转换为float...但当然不能隐式转换回Int,因为精度会丢失。这就是为什么我称C#为“大多数强类型”的原因。将Int隐式转换为Float是鸭子类型。当Float不是Int时抛出错误是强类型。 - Daniel Westcott
显示剩余2条评论

2

这里有一篇博客文章,作者曾是C#编译器的主要开发者(在他写这篇文章的时候)。

简而言之,问题本身存在缺陷,无法以其当前的形式合理回答。


5
这就是为什么存在关闭投票:P - BoltClock
7
@BoltClock 嗯,答案是没有答案,而不是“我们都无法找出答案”。实际上,有一个相当好的解释可以说明为什么不能有任何答案,这就是为什么我没有投票关闭。 - Servy

2
有关强类型和弱类型,存在许多定义,到了需要在使用时定义术语的程度。我发现一个有用的定义是“语言是否强制我为参数等事物指定类型?”这将C#等语言与Javascript等语言分开,我认为这种区别很有用。
要求某人命名类型而不是依赖于“鸭子类型”会在静态分析方面带来优势,但在指定共享常见功能的类型方面则会带来劣势。因此,许多这些语言发展出复杂的类型关系规范系统,通常首先是基于类的编程,然后是复杂的模板系统或推断系统,以便程序员可以说出“类型A是类型B的子集”或“类型C是可以应用于满足条件D和E的任何其他类型的元类型”等等。

然而,在一些情况下,C#允许所谓的"鸭子类型",这也是非强类型语言的特征。最常见的例子就是foreach循环,它适用于任何具有GetEnumerator方法的对象。 - Servy
2
@Plynx 实际上有点像;它是基于名称/签名,而不是特定的接口。其他例子包括LINQ和await - Marc Gravell
2
@Plynx(附上您的评论编辑)不,您是错误的。foreach不需要这些接口。这些接口保证这些签名,但即使没有它们,该功能也可以正常工作。 - Marc Gravell
1
@Plynx 自 C# 1.2 开始(foreach)就是这种情况,甚至可能在此之前(我手头没有 1.0 规范)。LINQ 是在 3.5 中引入的。 - Marc Gravell
1
请注意,这只是一个示例,而且是比较常见的一个。还有许多其他的例子。马克提到了一些,当然还有 dynamic,再往后就是在 unsafe 代码中所能完成的一切,可以完全摧毁对于托管代码程序状态所做出的任何假设。 - Servy
显示剩余4条评论

1
根据MSDN,C# 是一种强类型语言。

5
MSDN也是错误的,因为编写一个不是强类型的C#程序非常简单。C#可以编写强类型程序,但没有任何强制要求。 - Servy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接