你应该在 C# 中使用指针(不安全代码)吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/584134/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Should you use pointers (unsafe code) in C#?
提问by Kredns
Should you use pointers in your C# code? What are the benefits? Is it recommend by The Man (Microsoft)?
你应该在你的 C# 代码中使用指针吗?有什么好处?是 The Man (Microsoft) 推荐的吗?
采纳答案by nzpcmad
From "The Man" himself:
来自“男人”本人:
The use of pointers is rarely required in C#, but there are some situations that require them. As examples, using an unsafe context to allow pointers is warranted by the following cases:
在 C# 中很少需要使用指针,但在某些情况下需要它们。例如,在以下情况下可以使用不安全的上下文来允许指针:
- Dealing with existing structures on disk
- Advanced COM or Platform Invoke scenarios that involve structures with pointers in them
- Performance-critical code
- 处理磁盘上的现有结构
- 涉及带有指针的结构的高级 COM 或平台调用方案
- 性能关键代码
The use of unsafe context in other situations is discouraged.
不鼓励在其他情况下使用不安全的上下文。
Specifically, an unsafe context should not be used to attempt to write C code in C#.
具体来说,不应该使用不安全的上下文来尝试在 C# 中编写 C 代码。
Caution:
警告:
Code written using an unsafe context cannot be verified to be safe, so it will be executed only when the code is fully trusted. In other words, unsafe code cannot be executed in an untrusted environment. For example, you cannot run unsafe code directly from the Internet.
使用不安全上下文编写的代码无法验证是否安全,因此只有在代码完全受信任时才会执行。换句话说,不安全的代码不能在不受信任的环境中执行。例如,您不能直接从 Internet 运行不安全的代码。
回答by Jon Skeet
I can't remember ever having to do so - but I haven't done much interop. That's the most common application, I believe: calling into native code. There are a very few times where using pointers allows you to optimise some code, but it's pretty rare in my experience.
我不记得曾经这样做过 - 但我没有做过太多的互操作。我相信这是最常见的应用程序:调用本机代码。使用指针可以让您优化某些代码的情况很少见,但在我的经验中这种情况很少见。
If it's any guide, I consider myself to be pretty experienced in C# but if I had to do any unsafe code I'd have to consult the spec/books/MSDN to guide me. Of course there will be plenty of people who are happy with unsafe code but less familiar with (say) query expressions...
如果有任何指南,我认为自己在 C# 方面非常有经验,但是如果我必须执行任何不安全的代码,我必须查阅规范/书籍/MSDN 来指导我。当然,会有很多人对不安全的代码感到满意,但对(比如说)查询表达式不太熟悉……
回答by Greg Beech
You should use them if you need them; mostly this will be when dealing with some tricky interop scenarios (for example when I wrote a managed wrapper for DPAPI in .NET 1.0 they were needed) but very occasionally it might be to improve performance (after profiling!) by using stackalloc
or similar.
如果需要,您应该使用它们;这主要是在处理一些棘手的互操作场景时(例如,当我在 .NET 1.0 中为 DPAPI 编写托管包装时需要它们),但偶尔可能会通过使用stackalloc
或类似来提高性能(在分析之后!)。
It is recommended by Microsoft in as much as they are the designers of C#, and they made the decision to add the capability to write unsafe
code in it. You can see from the choice of keyword and the requirement to delineate the methods/classes in which you write it using the keyword, that it isn't designed to be the de-facto implementation choice.
Microsoft 和 C# 的设计者一样推荐使用它,并且他们决定添加在其中编写unsafe
代码的功能。您可以从关键字的选择和使用关键字描述编写它的方法/类的要求中看到,它不是设计为事实上的实现选择。
回答by Al W
course it isn't "recommended", that's why it's labeled "unsafe". But don't let that scare you away. Although, it should make you look twice at your code. Perhaps there is a managed way to do it?
当然它不是“推荐”,这就是为什么它被标记为“不安全”。但不要让它吓到你。虽然,它应该让你看两遍你的代码。也许有一种管理的方法来做到这一点?
回答by Rex M
Unsafe codeis a fully supported function of the .NET CLR. The benefits are performance and compatibility with binary code. The runtime is a sandbox which prevents you from crashing and burning, but that comes with a cost. In situations where you are doing extremely intensive operations against large blobs in memory, for example image manipulation, it is faster to step outside the normal safety the runtime provides.
不安全代码是 .NET CLR 完全支持的功能。好处是性能和与二进制代码的兼容性。运行时是一个沙箱,可以防止您崩溃和烧毁,但这需要付出代价。在对内存中的大型 blob 执行极其密集的操作(例如图像处理)的情况下,跳出运行时提供的正常安全性会更快。
That having been said, I think mostpeople here would say "don't do it". The vast majority of .NET developers will not run into a case in their normal activities that can only be solved by using unsafe code.
话虽如此,我认为这里的大多数人都会说“不要这样做”。绝大多数 .NET 开发人员在他们的正常活动中不会遇到只能通过使用不安全代码来解决的情况。
回答by Ed S.
If you have to.
如果你必须这样做。
Say that you need to false color a large grayscale image, say 2000x2000 pixels. First write the 'safe' version using GetPixel()
and SetPixel()
. If that works, great, move on. if that proves to be too slow, you may need to get at the actual bits that make up the image (forget about Color matrices for the sake of the example). There is nothing 'bad' about using unsafe code, but it adds complexity to the project and should thus be used only when necessary.
假设您需要对大型灰度图像(例如 2000x2000 像素)进行伪彩色处理。首先使用GetPixel()
和编写“安全”版本SetPixel()
。如果那行得通,那太好了,继续前进。如果这被证明太慢,您可能需要获取构成图像的实际位(为了示例而忘记颜色矩阵)。使用不安全代码并没有什么“坏处”,但它增加了项目的复杂性,因此应仅在必要时使用。
回答by Otávio Décio
I used unsafe code to use impersonation to allow services access to network shares. It is not a problem if you know what you're doing.
我使用不安全代码来使用模拟来允许服务访问网络共享。如果你知道自己在做什么,这不是问题。
回答by Oscar Cabrero
using Unsafe code is like forgetting the benenfits of the .Net Framework, i used them once to created old fashioned structures like stacks and stuff but that was only for school, nowadays i havent had the need to use them.
使用 Unsafe 代码就像忘记了 .Net Framework 的好处,我曾经使用它们来创建老式结构,如堆栈和其他东西,但这仅适用于学校,现在我不需要使用它们。
回答by daonb
回答by ShuggyCoUk
Reinterpretive like casts not supplied by BitConverter.
Specifically converting a unint into an int for hash functions where all you care about is the bits.
像 BitConverter 不提供的强制转换一样重新解释。
专门将 unint 转换为 int 以用于散列函数,您只关心位。
Using some useful, well reasoned about c or C++ idiomatic functions on structs where you need to treat them as a byte* of a well known length, again most useful for hashing.
在结构上使用一些有用的、有充分理由的关于 c 或 C++ 惯用函数,您需要将它们视为已知长度的字节 *,同样对散列最有用。
Extremely fast binary serialization of (very specific) in memory structs (by doing it to an array of them) though to be honest this is better done by just dropping to C++/CLI.
内存结构中(非常具体的)非常快速的二进制序列化(通过对它们的数组进行)尽管说实话,这最好通过直接使用 C++/CLI 来完成。
It must be said that in many cases the task requiring pointers can often be solved better by doing it in C++/CLI and then importing this into you c# project as a dll. It doesn't change whether the code is 'safe' or not but it makes a bunch of useful functions for operating on pointer based structures more accessible. It also allows you to mess about with generic types or enums if you really want to.
必须指出的是,在许多情况下,需要指针的任务通常可以通过在 C++/CLI 中完成,然后将其作为 dll 导入到您的 c# 项目中来更好地解决。它不会改变代码是否“安全”,但它使一系列用于操作基于指针的结构的有用函数更易于访问。如果您真的愿意,它还允许您使用泛型类型或枚举。
The likelihood of most developers needing to do this is indeed remote. Useful when you need it though...
大多数开发人员需要这样做的可能性确实很小。不过在你需要的时候很有用...