Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 连接对象的字符串表示的好方法?_C#_Optimization_Extension Methods_Memory Management - Fatal编程技术网

C# 连接对象的字符串表示的好方法?

C# 连接对象的字符串表示的好方法?,c#,optimization,extension-methods,memory-management,C#,Optimization,Extension Methods,Memory Management,嗯 我们的代码中有很多where子句。我们有同样多的方法来生成一个字符串来表示in条件。我试图想出一个干净的方法,如下所示: public static string Join<T>(this IEnumerable<T> items, string separator) { var strings = from item in items select item.ToString(); return string.Join(separator, stri

我们的代码中有很多where子句。我们有同样多的方法来生成一个字符串来表示in条件。我试图想出一个干净的方法,如下所示:

public static string Join<T>(this IEnumerable<T> items, string separator)
{
    var strings = from item in items select item.ToString();
    return string.Join(separator, strings.ToArray());
}
var values = new []{1, 2, 3, 4, 5, 6};
values.StringJoin(",");
// result should be:
// "1,2,3,4,5,6"
这是一个很好的扩展方法,它完成了一项非常基本的工作。我知道简单的代码并不总是能够快速或高效地执行,但我很好奇,这个简单的代码会错过什么。我们团队的其他成员认为:

  • 它不够灵活(无法控制字符串表示)
  • 可能没有内存效率
  • 可能不会很快
有专家插话吗

问候,

Eric.

这也适用于:

public static string Test(IEnumerable<T> items, string separator)
{
    var builder = new StringBuilder();
    bool appendSeperator = false;
    if(null != items)
    {
        foreach(var item in items)
        {
            if(appendSeperator)
            {
                builder.Append(separator)
            }

            builder.Append(item.ToString());

            appendSeperator = true;
        }
   }

   return builder.ToString();
}
公共静态字符串测试(IEnumerable项,字符串分隔符)
{
var builder=新的StringBuilder();
bool appendseparator=false;
如果(空!=项目)
{
foreach(项目中的var项目)
{
if(附件分离器)
{
builder.Append(分隔符)
}
Append(item.ToString());
appendseparator=true;
}
}
返回builder.ToString();
}

序列和序列项缺少空检查。是的,这不是最快和最节省内存的方法。您可能只需枚举序列并将项目的字符串表示形式呈现到
StringBuilder
中。但这真的重要吗?您是否遇到性能问题?您需要优化吗?

为什么不使用StringBuilder,自己在集合中迭代,并添加。
否则,您将创建一个字符串数组(var strings),然后执行连接。

出于某种原因,我认为
String.Join
是根据
StringBuilder
类实现的。但如果不是这样,那么下面的方法对于大型输入可能会执行得更好,因为它不会为迭代中的每个连接重新创建
字符串
对象

public static string Join<T>(this IEnumerable<T> items, string separator)
{
    // TODO: check for null arguments.
    StringBuilder builder = new StringBuilder();
    foreach(T t in items)
    {
        builder.Append(t.ToString()).Append(separator);
    }

    builder.Length -= separator.Length;
    return builder.ToString();
}
公共静态字符串联接(此IEnumerable项,字符串分隔符)
{
//TODO:检查空参数。
StringBuilder=新的StringBuilder();
foreach(以项目为单位)
{
Append(t.ToString()).Append(分隔符);
}
builder.Length-=分隔符.Length;
返回builder.ToString();
}

编辑:以下是使用
StringBuilder
String.Join

关于第一个问题,您可以添加另一个“formatter”参数来控制将每个项转换为字符串:

public static string Join<T>(this IEnumerable<T> items, string separator)
{
    return items.Join(separator, i => i.ToString());
}

public static string Join<T>(this IEnumerable<T> items, string separator, Func<T, string> formatter)
{
    return String.Join(separator, items.Select(i => formatter(i)).ToArray());
}
公共静态字符串联接(此IEnumerable项,字符串分隔符)
{
returnitems.Join(分隔符,i=>i.ToString());
}
公共静态字符串联接(此IEnumerable项、字符串分隔符、Func格式化程序)
{
返回String.Join(分隔符,items.Select(i=>formatter(i)).ToArray();
}

关于后两个问题,我不会担心,除非您以后遇到性能问题并发现这是一个问题。这不太可能是一个瓶颈,但是…

Join()使用直接访问字符串的字符数组,速度至少会一样快。Steve,有趣的是,您展示了我对StringBuilder方法的确切关注。如果你环顾四周,你的算法有几十种变化。实际上,受String.Join()方法(谢谢你)的启发,我可能会遵循他们的模式。我希望更多的人会在这里发布他们的算法,并用一些硬数据支持他们的偏好。但这是一个有趣的话题。我在上发现了一个问题,分析了
StringBuilder
String.Join
的效率——请参见我的编辑以获取链接。+1链接作为扩展方法,检查
null
集合没有意义。不过,检查集合中的项数可能很好。我不明白第一点——如果它是一个实例方法,那么检查它是否为null是没有意义的,但是如果它是一个扩展方法,则必须检查序列,因为它可能会在null引用中被调用。这里的“in”条件在哪里?Lee,我同意你的看法。这是我与我的团队最初的争论。我们还没有发现任何实际的性能瓶颈。至少通过这种方法,您可以在一个地方轻松地更新实现,我们的整个应用程序都将从中受益。
Join
首选项+1,因为下面的链接表明性能差异可以忽略,可读性/简单性是首选项。