这段代码为什么没有unsafe关键字?在回答他自己有争议的问题时,Mash表示您不需要“不安全”关键字来直接读取和写入任何.NET对象实例的字节。您可以声明以下类型:[StructLayout(LayoutKind.Explicit)]structMemoryAccess{[FieldOffset(0)]publicobjectObject;[FieldOffset(0)]publicTopBytes字节数;}classTopBytes{公共字节b0;公共字节b1;公共公共字节b2;公共字节b3;公共字节b4;公共字节b5;公共字节b6;公共字节b7;;公共字节b15;然后你可以做一些事情,比如改变一个“不可变”的字符串。以下代码在我的机器上打印“bar”:stringfoo="foo";内存访问mem=new内存访问();mem.Object=foo;mem.Bytes.b8=(byte)'b';内存.字节。b10=(byte)'a';mem.Bytes.b12=(byte)'r';控制台.WriteLine(foo);您还可以使用相同的技术通过中断对象引用来触发AccessViolationException。问题:我认为(在纯托管C#代码中)unsafe关键字是执行此类操作所必需的。为什么这里没有必要?这是否意味着纯托管的“安全”代码根本不安全?好吧,这很讨厌……使用工会的危险。这可能有用,但不是一个好主意——我想我会把它比作反射(你可以做大部分事情)。我有兴趣看看它是否在受限访问环境中工作——如果是这样,它可能代表一个更大的问题……我只是在没有“完全信任”标志的情况下测试它,它在运行时被拒绝:无法从程序集安装“ConsoleApplication4,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”加载类型“MemoryAccess”,因为对象在偏移量0处重叠并且程序集必须是可验证的。要拥有此标志,您已经需要高度信任-因此您已经可以做更多令人讨厌的事情。字符串的情况略有不同,因为它们不是普通的.NET对象——但还有其他方法可以改变它们——但“联合”方法是一种有趣的方法。对于另一种hacky方式(有足够的信誉):stringorig="abc",copy=orig;typeof(string).GetMethod("AppendInPlace",BindingFlags.NonPublic|BindingFlags.Instance,null,newType[]{typeof(string),typeof(int)},null).Invoke(orig,newobject[]{"定义”,3});控制台.WriteLine(复制);//注意我们没有触及“复制”,所以我们对相同的引用进行了变异//哎呀,我已经修复了不安全。这是一个更正后的版本:示例代码不需要用unsafe关键字标记的原因是它不包含指针(请参阅下面的引文,为什么这被认为是不安全的)。您完全正确:“安全”可能更适合称为“运行时友好”。有关此主题的详细信息,请参阅DonBox和ChrisSellsEssential.NETQuotingMSDN,在公共语言运行时(CLR)中,不安全代码称为未验证代码。C#中的不安全代码不一定是危险的;它只是CLR无法验证其安全性的代码。因此,CLR只会在完全受信任的程序集中执行不安全的代码。如果您使用不安全的代码,您有责任确保该代码不会引入安全风险或指针错误。fixed和unsafe的区别在于fixed阻止CLR移动内存中的东西,所以运行时之外的东西可以安全地访问它们,而unsafe有完全相反的问题:CLR可以保证正确解析dotnet引用,它不能为指针做这个。您可能还记得各种Microsoft关于引用不是指针的说法,这就是为什么他们对细微的区别大惊小怪。您仍然选择退出“托管”位。有一个潜在的假设,如果你能做到这一点,那么你就知道自己在做什么。以上就是C#学习教程:为什么这段代码没有unsafe关键字?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
