使用StringBuilder反射的无垃圾String类未正确初始化

are*_*mes 1 c# string xna garbage-collection xna-4.0

我试图根据这里的注释创建一个自定义StringBuilder类.

这是我目前的代码:

class MyStringBuilder
{
    public StringBuilder stringBuilder;
    public String linkToStringBuilderString;

    public MyStringBuilder(int maxCapacity)
    {
        stringBuilder = new StringBuilder(maxCapacity, maxCapacity);

        linkToStringBuilderString = (String)stringBuilder.GetType().GetField("m_StringValue", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(stringBuilder);
    }
};
Run Code Online (Sandbox Code Playgroud)

但是,应该获取内部StringBuilder字符串的永久链接的构造函数的最后一行给出了我的空引用编译错误,我不明白为什么.

Col*_*ell 5

让我们分解失败的路线.

我是认真的.从字面上看.正如您所发现的那样,它正在做得太多,难以调试.所以让我们改写它.

linkToStringBuilderString = (String)stringBuilder.GetType().GetField("m_StringValue", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(stringBuilder);
Run Code Online (Sandbox Code Playgroud)

那是在做很多事情.让我们把每个操作放在自己的行上:

var type = stringBuilder.GetType();
var field = type.GetField("m_StringValue", BindingFlags.NonPublic | BindingFlags.Instance);
var value = (String)field.GetValue(stringBuilder);
Run Code Online (Sandbox Code Playgroud)

现在,Visual Studio应该让您更清楚地了解抛出异常时失败的原因.

当我运行此代码时,我得到一个这样的代码NullReferenceException:

var value = field.GetValue(stringBuilder);
Run Code Online (Sandbox Code Playgroud)

这意味着它field是null.为什么会出现这种情况?好吧,GetField()如果您请求的字段实际上不存在,则返回null.当您依赖BCL类的内部实现细节时会发生这种情况.

StringBuilder在dotPeek(它在mscorlib)中打开课程,我看不到任何成员的名字m_StringValue.字符串使用一系列动态分配的数组存储; 它似乎没有以字符串形式缓存.

看看版本2.0 mscorlib,我看到曾经有一个这个名字的字段.因此,当.NET 4问世时,这个类显然已被重构.同样,这些是依赖于内部实现细节的问题.

您链接的网站上还有另一篇文章详细说明了这个问题.希望这个答案可以帮助您指出自己未来的正确方向.