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

时间:2018-11-06 07:01:46

标签: c# .net .net-core

我开始研究称为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”字符串吗?

1 个答案:

答案 0 :(得分:1)

这就是它的工作方式

MemoryMarshal.AsMemory(ReadOnlyMemory) Method

  

从ReadOnlyMemory创建一个内存实例。

     

返回    -Memory<T>一个内存块,用于重新预置与ReadOnlyMemory相同的内存。

     

备注

     
      
  • 必须非常谨慎地使用此方法。 ReadOnlyMemory用于表示不可变数据和其他不旨在   被写入。 通过此方法创建的内存实例不应   写入。此方法的目的是允许输入变量   作为内存,但仅用于读取以存储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