在C#中真正使用过指针吗?[关闭]


19

在C#中编码时,使用指针是一个好选择还是必须选择的情况是什么?我说的是不安全的指针。


8
啊,伙计,我看到了问题并很高兴,因为我要解释一下,在C#中,您一直都在使用指针,但是您必须通过明确地说出不安全的关键字来破坏指针。该死的!:)
托尼2010年

Answers:


25

来自C#开发人员本人:

在C#中很少需要使用指针,但是在某些情况下需要使用指针。作为示例,在以下情况下需要使用不安全的上下文来允许指针:

  • 处理磁盘上的现有结构
  • 涉及结构中包含指针的高级COM或平台调用方案
  • 关键性能代码

不建议在其他情况下使用不安全的上下文。

特别是,不应使用不安全的上下文来尝试用C#编写C代码。

警告: “无法验证使用不安全上下文编写的代码是否安全,因此只有在完全信任该代码时才能执行。换句话说,不能在不可信环境中执行不安全代码。例如,您不能运行不安全直接从互联网上进行编码。”

你可以去通过这个供参考


“不安全的代码不能在不受信任的环境中执行。” 您是说“信任”吗?
Don Larynx 2015年

18

是的,当性能很关键而操作是低级的时候,有实际用途

例如,对于图像比较,我只需要在C#中使用一次指针即可。在一对1024x1024x32的图像上使用GetPixel进行比较需要2分钟(完全匹配)。固定图像内存并使用指针花了不到1秒的时间(当然是在同一台机器上)。


2
我已在你们使用LockBits为...(msdn.microsoft.com/en-us/library/...
配置器

1
@configurator:这是.net 2,LockBits不存在
Steven A. Lowe 2010年

2
当然可以,它从1.0开始就存在...
configurator 2010年

@configurator:我的错误,我在浏览MSDN文档时感到困惑(当我在下拉列表中更改为.net 2时,它转到了一个完全不同的页面,其中没有提到锁位)。是的,这就是固定图像存储器的方式。
史蒂文·A·劳

6

您必须记住,Microsoft的设计师是聪明的人,他们添加到C#中的所有内容至少都有一个用例。该FParsec项目使用不安全的代码带出的性能的每一个最后一滴,C#语言是可以胜任的。就拿使用的通知fixedstackalloc

private char* ReadCharsFromStream(char* buffer, int maxCount, out string overhangChars) {
    Debug.Assert(maxCount >= 0);
    fixed (byte* byteBuffer = ByteBuffer) {
        overhangChars = null;
        try {
            while (maxCount >= MaxCharCountForOneByte) {// if maxCount < MaxCharCountForOneByte, Convert could throw
                int nBytesInByteBuffer = FillByteBuffer();
                bool flush = nBytesInByteBuffer == 0;
                int bytesUsed, charsUsed; bool completed = false;
                Decoder.Convert(byteBuffer + ByteBufferIndex, nBytesInByteBuffer,
                                buffer, maxCount, flush,
                                out bytesUsed, out charsUsed, out completed);
                ByteBufferIndex += bytesUsed; // GetChars consumed bytesUsed bytes from the byte buffer
                buffer += charsUsed;
                maxCount -= charsUsed;
                if (flush && completed) return buffer;
            }
            if (maxCount == 0) return buffer;

            char* cs = stackalloc char[MaxCharCountForOneByte];
            for (;;) {
                int nBytesInByteBuffer = FillByteBuffer();
                bool flush = nBytesInByteBuffer == 0;
                int bytesUsed, charsUsed; bool completed;
                Decoder.Convert(byteBuffer + ByteBufferIndex, nBytesInByteBuffer,
                                cs, MaxCharCountForOneByte, flush,
                                out bytesUsed, out charsUsed, out completed);
                ByteBufferIndex += bytesUsed;
                if (charsUsed > 0) {
                    int i = 0;
                    do {
                        *(buffer++) = cs[i++];
                        if (--maxCount == 0) {
                            if (i < charsUsed) overhangChars = new string(cs, i, charsUsed - i);
                            return buffer;
                        }
                    } while (i < charsUsed);
                }
                if (flush && completed) return buffer;
            }
        } catch (DecoderFallbackException e) {
            e.Data.Add("Stream.Position", ByteIndex + e.Index);
            throw;
        }
    }
}

1
我想说,如果开发人员(包括Microsoft或任何其他公司)具有某些用例,那么它们将是一个白痴,因为它只有1个用例。一个功能不应该只有1个用例。否则就是a肿。
Lie Ryan 2010年

4
雷蒙德·陈(Raymond Chen)经常说,微软的功能始于-100点。为了实现一项功能,它“必须对整个程序包产生重大的净正面影响”。这是ericgu关于此c.2004的博客文章:blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx
Jesse Buchanan 2010年

我很确定某些String操作在内部使用不安全的代码。因此,FParsec可能不是优先级。
Arturo TorresSánchez16年

4

我曾经不得不在基于C#的Windows应用程序中使用指针(在不安全的上下文中),它将用作耳机的接口。该应用程序是一个用户界面,允许座席(在呼叫中心)控制其耳机设置。此应用程序替代耳机制造商提供的控制面板。因此,与可用选项相比,它们控制耳机的能力受到限制。我必须使用指针,因为必须使用耳机制造商使用P / Invoke提供的API(Visual C ++ dll)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.