سؤال

نعم،

لدينا الكثير من أين البنود في الكود الخاص بنا.لدينا العديد من الطرق لإنشاء سلسلة لتمثيل في حالة.أحاول التوصل إلى طريقة نظيفة على النحو التالي:

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"

إذن فهذه طريقة تمديد رائعة تقوم بعمل أساسي للغاية.أعلم أن التعليمات البرمجية البسيطة لا تتحول دائمًا إلى تنفيذ سريع أو فعال، ولكن لدي فضول لمعرفة ما قد فاتني من خلال هذه التعليمات البرمجية البسيطة.ويجادل أعضاء آخرون في فريقنا بما يلي:

  • ليست مرنة بدرجة كافية (لا يوجد تحكم في تمثيل السلسلة)
  • قد لا تكون فعالة في الذاكرة
  • قد لا يكون سريعا

أي خبير لتتناغم؟

يعتبر،

اريك.

هل كانت مفيدة؟

المحلول

فيما يتعلق بالمسألة الأولى، يمكنك إضافة معلمة "تنسيق" أخرى للتحكم في تحويل كل عنصر إلى سلسلة:

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());
}

فيما يتعلق بالمشكلتين الثانيتين، فلا داعي للقلق بشأنهما إلا إذا واجهت مشكلات في الأداء لاحقًا ووجدت أنها مشكلة.ومع ذلك، فمن غير المرجح أن يحدث الكثير من عنق الزجاجة.

نصائح أخرى

لسبب ما، اعتقدت ذلك String.Join يتم تنفيذه من حيث أ StringBuilder فصل.ولكن إذا لم يكن الأمر كذلك، فمن المرجح أن يكون أداء ما يلي أفضل بالنسبة للمدخلات الكبيرة لأنه لا يعيد إنشاء ملف String كائن لكل صلة في التكرار.

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();
}

يحرر:هنا تحليل متى يكون مناسبًا للاستخدام StringBuilder و String.Join.

لماذا لا تستخدم StringBuilder، وتكرر المجموعة بنفسك، مع إلحاقها.وإلا فإنك تقوم بإنشاء مصفوفة من السلاسل (سلاسل var) ثم تقوم بعملية الانضمام.

تفتقد عمليات التحقق الخالية من التسلسل وعناصر التسلسل.ونعم، إنها ليست الطريقة الأسرع والأكثر كفاءة في الذاكرة.من المحتمل أن يقوم المرء فقط بتعداد التسلسل وتقديم تمثيلات السلسلة للعناصر في ملف StringBuilder.ولكن هل هذا مهم حقا؟هل تواجه مشاكل في الأداء؟هل تحتاج إلى التحسين؟

هذا من شأنه أن يعمل أيضا:

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();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top