我明白指针和罕见的需要使用他们在C#代码。我的问题是:什么是背后的推理具有明确说明"不安全"中的一块的代码。此外,为什么必须以一个编译器的选择以改变允许"不安全"的代码?

底线: 什么在CLR(或语言的规范)使得它如此,我们不能只是使用的指针每当我们想要的(如C、C++)没有必要类型的"不安全",改变编译器的选择吗?

为澄清:我知道什么是"不安全"和"安全"的代码。这只是一个问题为什么我们必须做所有的额外工作(确定,没有很多额外的)只是为了能够使用这些功能。

有帮助吗?

解决方案

接受C#Creator Anders Hejlsberg采访时涉及的问题这里。基本上,正是@Marc Gravell所说的:首先是类型安全,通过明确声明不安全。

所以回答你的问题:CLR中没有任何东西阻止它;它是一种语言习语,旨在让您在处理类型时使用安全手套。如果你想脱下手套,这是你的选择,但你必须做出积极的选择才能脱下手套。

修改

  

澄清:我知道什么   "不安全"和“安全”代码是。只是   我们为什么要做所有这一切的问题   额外的工作(好吧,不是多多额外的)   只是为了能够使用这些功能。

正如我所接受的采访中提到的,这是一个明确的设计决定。 C#本质上是Java的演变,在Java中,你根本就没有指针。但设计师想要指点;但是因为C#通常会引入Java开发人员,他们认为如果默认行为与Java类似,即没有指针,同时仍允许通过显式声明使用指针,那将是最好的。

所以“额外的工作”故意强迫你在做之前考虑你在做什么。通过明确,它迫使你至少考虑:“为什么我这样做?当参考类型足够时,真的是否需要指针?“

其他提示

主要是关于可验证的。通过声明 unsafe ,手套关闭 - 系统无法保证您的代码不会无法正常运行。在大多数情况下,非常希望留在安全区。

使用部分信任(插件等)会更加明显,但在常规代码中仍然很有价值。

实际上,CLR对/ unsafe开关或关键字没有任何要求。事实上,C ++ / CLI(在CLR下运行的C ++语言)没有这样/不安全的开关,并且指针可以在CLR上自由使用。

所以我将你的问题改为“为什么C#在使用指针之前需要使用/ unsafe?”这个问题的答案如此处给出的其他答案中所述:帮助用户有意识地决定失去在CLR上以低于完全信任模式运行的能力。 C ++几乎总是需要CLR上的完全信任,并且只要您调用需要完全信任的代码,或者无论何时使用指针,C#都可以

当您使用不安全的块时,它会使代码无法验证。这需要执行某些权限,您可能不希望在输出中允许它(特别是如果您在共享源环境中),因此编译器中有一个禁止它的开关。

想想看从相反的观点:因为它并不标志着不安全,可以推断,大多数代码是"安全"默认。那么是什么意思是"安全"?为。净码,这包括(但可能不限于):

  • 垃圾收集器可以做一切如常。
  • 引用一种特定类型 参照对象的类型(或null)。
  • 代码是保证遵守。Net信任与安全的要求。
  • 代码是数学上证明不直接接触的存储器之外它自己的程序域.它可能看起来微不足道,但是想象一下如果你有多个应用程序域在相同的应用程序。程序员可以满怀信心地对待他们,因为在逻辑上独立的。

任何时间使用的指针,你有机会破坏任何这些保障。因此,标识代码为不安全给这些保护措施。

在短.净希望你状态您的意图。

当然,编译器可以推断需要对"不安全"的标志。但是设计师们希望它是一种蓄意的决定。

对我来说,这是类似于一些句法要求在C#:

  • 没有开关的情况不断
  • 没有访问的级别"部分"(例如"公众"的标记在C++)
  • 没有类领域使用"var"

该模式是,你不应该移动或改变一件事情并不经意地影响到另一个。在合理的范围内,他们想让你从"搬起石头砸自己的脚。"

许多伟大的、内容翔实的答案在这里—也许这样更多的问题。

因此,很明显,如果没有提升权限等,哪些代码将无法在Web服务中运行。

养成良好的习惯&安全。每当在程序集中使用不安全的块时,都会从堆栈中请求NativeCode权限。这当然可以隐式完成,但我们不能完全删除private关键字吗?我认为强迫开发人员在使用之前专门要求不安全的代码是好的。

安全和不安全代码之间最显着的区别是.net的垃圾收集器无法访问不安全的代码。自动GC是.net白话的一个重要组成部分,当你超越它的界限时,你会改变很多关于代码的假设。

指针特别允许在堆上创建没有GC引用的对象。这导致要求将代码标记为“不安全”的另一个极好的理由。当您意识到有内存泄漏时,可以轻松缩小内存泄漏的范围。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top