这会覆盖我的字符串的内容:
unsafe
{
fixed (char* chars = str)
{
for (int i = 0; i < str.Length; i++)
chars[i] = '1';
}
}
背景是我正在使用NetworkCredientials,您可以使用普通的System.String
设置密码。如果可能的话,之后我想“清除它”。有关如何执行此操作的任何建议都是受欢迎的,但主要问题是要了解fixed
是否真的允许我访问底层char数组。谢谢!
修改
我想了解 在这里发生了什么 - 如果字符串对象是不可变的,并且fixed
不让对象移动那么发布的代码中发生了什么?这些字符写在哪里?
答案 0 :(得分:12)
请改用NetworkCredentials
constructor overload taking SecureString
。过载的全部原因是为了避免这个问题。你不应该试图改变System.String
实例。 (这当然可以通过反思,但应该避免。)
答案 1 :(得分:6)
System.String
是不可变的,因此您无法对其进行修改。
字符串是不可变的 - 字符串对象的内容不能 在创建对象后更改,尽管语法可以实现 好像你可以这样做。
如果出于安全原因需要删除字符串,请尝试查看SecureString。
事实上,你的代码改变了字符串,你可以在这里看到Eric Lippert的回答:String immutability in C#:
您可以创建CLR在其上强制实现不变性的类型。您 然后可以使用“不安全”来关闭CLR执行机制。 这就是为什么“不安全”被称为“不安全” - 因为它关闭了 安全系统。在不安全的代码中的每个字节的内存 如果你足够努力,包括两者都可以写进程 不可变字节和CLR中强制不变性的代码。
如果你真的只限于没有SecureString
的C#版本,那么你必须使用不安全的代码。但也许最好的解决方案是更加努力地改变版本。
答案 2 :(得分:2)
我想了解这里发生了什么 - 如果一个字符串对象是不可变的,并且修复了不让对象移动那么发布的代码中发生了什么?这些字符写在哪里?
如果按照规则玩,字符串只是不可变的。在这里,您实际上是通过使用不安全的代码来改变字符串。 (甚至可以使代码在传递peverify
的意义上是“安全的”,但是以其他方式使规则弯曲,例如通过反射调用非公共AppendInPlace
方法或{{} 3}}。)
违反这样的规则是危险的。它可能干扰abusing union structs。它可能会破坏.NET运行时所依赖的内存位置,例如每个.NET对象开头存在的TypeHandle和syncblk字节。等