C#: Benefit of explicitly stating “unsafe” / compi

2020-03-13 17:06发布

I understand pointers and the rare need to use them in C# code. My question is: what is the reasoning behind having to explicitly state "unsafe" in a block of code. Additionally, why must a compiler option be changed to allow "unsafe" code?

Bottom Line: What in the CLR (or language specs) makes it so we can't just use pointers whenever we want (much like C and C++) without having to type "unsafe" and change the compiler option?

For clarification: I know what "unsafe" and "safe" code is. It's just a question of why must we do all the extra work (ok, not THAT much extra) just to be able to use these features.

9条回答
对你真心纯属浪费
2楼-- · 2020-03-13 17:59

Think about it from the opposite point of view: because it's not marked unsafe, you can infer that most code is "safe" by default. So what does it mean to be "safe"? For .Net code, this includes (but may not be limited to):

  • The garbage collector can do business as usual.
  • References to a specific type will refer to objects of that type (or null).
  • Code is guaranteed to comply with .Net trust/security requirements.
  • The code is mathematically proven not to directly touch memory outside it's own AppDomain. It may seem trivial, but imagine if you have multiple AppDomains in the same application. The programmer can confidently treat them as logically separate.

Any time you use pointers you have the chance to break any of those guarantees. Therefore marking code as unsafe gives up those protections.

查看更多
我只想做你的唯一
3楼-- · 2020-03-13 18:02

When you use an unsafe block, it has the effect of making the code unverifiable. This requires certain permissions to execute and you might not want to allow it in your output (especially if you are in a shared source environment), so there is a switch in the compiler to disallow it.

查看更多
淡お忘
4楼-- · 2020-03-13 18:05

In short, .NET wants you to state your intent.

Sure, the compiler could infer the need for the "unsafe" flag. But the designers want it to be a deliberate decision.

To me, it's akin to a number of syntactic requirements in C#:

  • no switch case without break
  • no access-level "sections" (such as the "public:" marker in C++)
  • no class fields using "var"

The pattern is that you shouldn't move or change one thing and inadvertently affect another. Within reason, they want to keep you from "shooting yourself in the foot."

Lots of great, informative answers here — maybe this goes more to your question.

查看更多
登录 后发表回答