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

问题描述 投票:4回答:1

我开始深入研究名为Span和Memory的新的C#/ .net核心功能,到目前为止它们看起来非常好。但是,当我遇到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);

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

有没有办法阻止这种行为?是否可以“unintern”字符串?

c# .net .net-core
1个回答
1
投票

这就是它的工作方式

MemoryMarshal.AsMemory(ReadOnlyMemory) Method

从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();
}

产量

fmmutable string1
immutable string2
© www.soinside.com 2019 - 2024. All rights reserved.