当前位置:  开发笔记 > 编程语言 > 正文

为什么我永远不会使用不安全的块来修改字符串?

如何解决《为什么我永远不会使用不安全的块来修改字符串?》经验,为你挑选了3个好方法。

我有一个字符串,我想以某种方式修改.例如:将其反转或将其翻转.

我发现最快的方法是使用不安全的块和指针.

例如:

        unsafe 
        {
            fixed (char* str = text)
            {
                *str = 'X';
            }
        }

有什么理由我永远不应该这样做吗?



1> Sam Saffron..:

.Net框架要求字符串是不可变的.由于这一要求,它能够优化各种操作.

字符串实习是这个要求被大量使用的一个很好的例子.为了加速一些字符串比较(并减少内存消耗),.Net框架维护一个指针字典,所有预定义的字符串将存在于此字典或您调用该String.intern方法的任何字符串中.当调用IL指令ldstr时,如果我们已经分配了字符串,它将检查被拦截的字典并避免内存分配,注意:String.Concat不会检查被拦截的字符串.

.net框架的这个属性意味着如果你开始直接使用字符串,你可以破坏你的实习表,反过来破坏对同一个字符串的其他引用.

例如:

         // these strings get interned
        string hello = "hello";
        string hello2 = "hello";

        string helloworld, helloworld2;

        helloworld = hello;
        helloworld += " world";

        helloworld2 = hello;
        helloworld2 += " world"; 

        unsafe
        {
            // very bad, this changes an interned string which affects 
            // all app domains.
            fixed (char* str = hello2)
            {
                *str = 'X';
            }

            fixed (char* str = helloworld2)
            {
                *str = 'X';
            }

        }

        Console.WriteLine("hello = {0} , hello2 = {1}", hello, hello2);
        // output: hello = Xello , hello2 = Xello  


        Console.WriteLine("helloworld = {0} , helloworld2 = {1}", helloworld, helloworld2);
        // output : helloworld = hello world , helloworld2 = Xello world  



2> Konrad Rudol..:

有什么理由我永远不应该这样做吗?

是的,非常简单:因为.NET依赖于字符串是不可变的这一事实.某些操作(例如s.SubString(0, s.Length))实际上返回对原始字符串的引用.如果现在修改了,那么所有其他引用也将如此.

最好使用a StringBuilder来修改字符串,因为这是默认方式.



3> Jon Skeet..:

这样说吧:如果另一个程序员在执行时决定用代码中的1替换0,你会有什么感觉?你会用你所有的假设来玩它.字符串也是如此.每个人都希望它们是不可变的,并考虑到这一假设.如果你违反了,你很可能会引入错误-他们会真的很难追查.

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有