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

时间:2013-11-18 14:54:36

标签: c# string xna garbage-collection xna-4.0

我正在尝试根据评论here创建自定义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);
    }
};

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

1 个答案:

答案 0 :(得分:5)

让我们分解失败的路线。

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

linkToStringBuilderString = (String)stringBuilder.GetType().GetField("m_StringValue", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(stringBuilder);

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

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

现在,Visual Studio可以让您更清楚地了解抛出异常时失败的原因。

当我运行此代码时,我会在此行中获得NullReferenceException

var value = field.GetValue(stringBuilder);

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

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

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

您链接的网站上有another article详细说明此问题。希望这个答案可以帮助您指出自己未来的正确方向。