C#通过Span/Memory和MemoryMarshal修改interned字符串

Ale*_*der 6 .net c# .net-core

我开始深入研究新的 C#/.net 核心功能(称为 Span 和 Memory),到目前为止它们看起来非常好。然而,当我遇到MemoryMarshal.AsMemory方法时,我发现了以下有趣的用例:

const string source1 = "immutable string";
const string source2 = "immutable string";

var memory = MemoryMarshal.AsMemory(source1.AsMemory());

ref char first = ref memory.Span[0];
first = 'X';

Console.WriteLine(source1);
Console.WriteLine(source2);
Run Code Online (Sandbox Code Playgroud)

两种情况下的输出都是Xmmutable string(在 Windows 10 x64、.net471 和 .netcore2.1 上测试)。据我所知,任何被保留的字符串现在都可以在一处进行修改,然后对该字符串的所有引用都将使用更新后的值。

有什么办法可以防止这种行为吗?是否可以“取消”字符串?

AAA*_*ddd 3

这就是它的工作原理

MemoryMarshal.AsMemory(ReadOnlyMemory) 方法

从 ReadOnlyMemory 创建 Memory 实例。

返回 -Memory<T> 表示与 ReadOnlyMemory 相同的内存的内存块。

评论

  • 使用此方法必须极其谨慎。ReadOnlyMemory 用于表示不可变数据和其他不打算写入的内存。不应将由此方法创建的内存实例写入. 此方法的目的是允许类型为 Memory 但仅用于读取的变量存储 ReadOnlyMemory

更多不应该做的事情

private const string source1 = "immutable string1";

private const string source2 = "immutable string2";

public unsafe static void Main()
{
   fixed(char* c = source1)
   {
      *c = 'f';
   }
   Console.WriteLine(source1);
   Console.WriteLine(source2);
   Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)

输出

fmmutable string1
immutable string2
Run Code Online (Sandbox Code Playgroud)