C# 如何获取附加到StringBuilder的最后一个字符串?

C# 如何获取附加到StringBuilder的最后一个字符串?,c#,stringbuilder,C#,Stringbuilder,在C#中,我有一个StringBuilder sb,我在for循环中多次添加它 对于StringBuilders,是否有一种简单的方法可以吐出附加到它的最后一个字符串?否。您可能应该使用一个字符串列表,然后将其连接起来,以替换StringBuilder功能,如下所示: List<string> strings = new List<string>(); strings.Add("..."); string result = string.Join("", strings)

在C#中,我有一个
StringBuilder sb
,我在for循环中多次添加它


对于
StringBuilders
,是否有一种简单的方法可以吐出附加到它的最后一个字符串?

否。您可能应该使用一个字符串列表,然后将其连接起来,以替换
StringBuilder
功能,如下所示:

List<string> strings = new List<string>();
strings.Add("...");
string result = string.Join("", strings);
string lastString = strings.Last();
sb.AppendRemember("hello").AppendRemember(" world");
string lastString = sb.LastAppended();

您可以创建自己的
StringBuilder
扩展方法来记住最后附加的字符串:

public static class StringBuilderExtensions
{
    public static string LastStringAppended { get; private set; }

    public static StringBuilder AppendRemember(this StringBuilder sb, object obj)
    {
        string s = obj == null ? "" : obj.ToString();
        LastStringAppended = s;
        return sb.Append(s);
    }
}
这样说吧

 sb.AppendRemember("hello").AppendRemember(" world");
 string lastString = StringBuilderExtensions.LastStringAppended;
但是,请注意,最后一个字符串将被全局记住。它未绑定到
StringBuilder
实例


如果需要记住每个
StringBuilder
实例的最后一次添加,可以通过字典将附加的“属性”附加到
StringBuilder
。我正在使用。这是必要的,因为
StringBuilder
覆盖
Equals
,并且不使用引用相等

public static class StringBuilderExtensions
{
    private static Dictionary<StringBuilder, string> _lastStrings =
        new Dictionary<StringBuilder, string>(
            new ObjectReferenceEqualityComparer<StringBuilder>());

    public static string LastAppended(this StringBuilder sb)
    {
        string s;
        _lastStrings.TryGetValue(sb, out s);
        return s; // s is null if not found in the dict.
    }

    public static StringBuilder AppendRemember(this StringBuilder sb, object obj)
    {
        string s = obj == null ? "" : obj.ToString();
        _lastStrings[sb] = s;
        return sb.Append(s);
    }
}

正如floele所回答的,你最好只是使用一个列表,然后加入其中。但正如Olivier Jacot Descombes和Tim Schmelter在他们的通信中所暗示的那样,您可以使用内部StringBuilder创建自己的类,然后只需从StringBuilder中重新创建要使用的方法,并将类中最后附加的字符串存储在属性中。与Olivier的答案相比,这有两个关键优势:记住的字符串不是“全局的”(它对每个实例都是唯一的),并且代码要简单很多倍

public class StringBuilderRemember
{
    private StringBuilder sb=new StringBuilder();
    public string LastString {get; private set;}

    public void AppendLine(string s)
    {
        LastString=s;
        sb.AppendLine(s);
    }
    public void Append(string s)
    {
        LastString=s;
        sb.Append(s);
    }
    public string ToString()
    {
    return sb.ToString();
    }
}

StringBuilder
不会跟踪所有更改。或者,您可以在每个字符串(最后一个除外)后面附加一个额外字符,然后使用
LastIndexOf()
提取最后一个字符串。当然,最后你必须用空字符串替换这些字符。你是说附加到现有字符串?这可能会成为一个性能问题,尽管这取决于元素的数量。如果他只需要最后一个字符串,他应该继续使用
StringBuilder
,但使用另一个字符串变量,该变量只保存附加的最后一个字符串。啊,是的,这确实也是一个简单的解决办法:)你真的认为利大于弊吗?与其使用静态字符串,我更希望使用从
StringBuilder
继承的自定义类,或者更好,只需使用一个
string
变量来跟踪最后附加的字符串。
StringBuilder
是一个密封类,因此无法从中继承。我想这是为了在框架中对其进行高度优化,而不让我们这些凡人搞砸。@Stayny:说得好,因此,您可以使用一个包含
StringBuilder
的类,或者没有额外的类/扩展,而只是一个跟踪的字符串。我添加了一个实现,它使用一个字典来记住每个
StringBuilder
实例的最后一个字符串。@OlivierJacot Descombes:方法和字典需要是静态的。在这种情况下,我不喜欢静态。你在不必要地打开潘多拉的盒子。