ما هي أفضل طريقة لتحويل كائن العنوان إلى سلسلة؟

StackOverflow https://stackoverflow.com/questions/600967

  •  03-07-2019
  •  | 
  •  

سؤال

لدي كائن عنوان يحتوي على خصائص addressline1 ، addressline2 ، الضاحية ، الحالة ، zipcode. (هناك المزيد ولكن هذا يكفي للمثال). أيضا ، كل من هذه الخصائص هي سلاسل. وأنا أستخدم C# 3.0.

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

على افتراض أن السلسلة المخصصة لكل خاصية هي نفس اسم الخاصية (IE addressline1 = "addressline1") ... أريد تمثيل العنوان على النحو التالي:

"addressline1 addressline2 Zipcode Zipcode state stature".

الآن ، كانت الطريقة الأصلية التي قمت بها من خلال سلسلة بسيطة.

String.Format("{0} {1} {2} {3} {4}", address.AddressLine1, 
address.AddressLine2, address.Suburb, address.State, address.ZipCode);

كل هذا جيدًا وجيدًا حتى وجدت أن بعض هذه الحقول يمكن أن تكون فارغة ... على وجه الخصوص Odventline2. والنتيجة هي مساحات إضافية غير ضرورية ... والتي تكون مزعجة بشكل خاص عندما تحصل على عدة على التوالي.

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

بمعنى آخر

string addressAsString = String.Empty;

if (!String.IsNullOrEmpty(address.AddressLine1))
{
    addressAsString += String.Format("{0}", address.AddressLine1);
}

if(!String.IsNullOrEmpty(address.AddressLine2))
{
    addressAsString += String.Format(" {0}", address.AddressLine2);
}

etc....

هل هناك طريقة أكثر أناقة و/أو موجزة لتحقيق ذلك لا أفكر فيها؟ الحل الخاص بي فقط يشعر فوضوي ومتضخم ... لكن لا يمكنني التفكير في طريقة أفضل للقيام بذلك ...

على كل ما أعرفه ، هذا هو خياري الوحيد بالنظر إلى ما أريد أن أفعله ... لكنني اعتقدت أنني سأرمي هذا هناك لمعرفة ما إذا كان شخص ما لديه خبرة أكثر مني يعرف طريقة أفضل. إذا لم يكن هناك خيار أفضل ، فهذا حسنًا ... ولكن إذا كان هناك ، فسوف أتعلم شيئًا لم أكن أعرفه من قبل.

شكرا مقدما!

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

المحلول

ربما ليست هذه هي الطريقة الأكثر كفاءة ، لكنها موجزة. يمكنك وضع العناصر التي تريدها في صفيف وتصفية العناصر دون قيمة كبيرة ، ثم انضم إليها.

var items = new[] { line1, line2, suburb, state, ... };
var values = items.Where(s => !string.IsNullOrEmpty(s));
var addr = string.Join(" ", values.ToArray());

ربما يكون القراءة أكثر كفاءة ، ولكن من الصعب إلى حد ما هو تجميع القيم في أ StringBuilder, ، على سبيل المثال

var items = new[] { line1, line2, suburb, state, ... };
var values = items.Where(s => !string.IsNullOrEmpty(s));
var builder = new StringBuilder(128);
values.Aggregate(builder, (b, s) => b.Append(s).Append(" "));
var addr = builder.ToString(0, builder.Length - 1);

من المحتمل أن أميل إلى شيء مثل التنفيذ الأول لأنه رمز أبسط وأكثر قابلاً للصيانة ، ثم إذا كان الأداء يمثل مشكلة ، ففكر في شيء أشبه بالثاني (إذا تحول إلى أسرع ...).

(لاحظ أن هذا يتطلب C# 3.0 ، لكنك لا تذكر إصدار لغتك ، لذلك أفترض أن هذا على ما يرام).

نصائح أخرى

عند وضع السلاسل معًا ، أوصي باستخدام فئة StringBuilder. السبب في ذلك هو أن النظام.

إذا كنت ترغب في تمثيل كائن في النص ، فقد يكون من الجيد تجاوز طريقة ToString () ووضع تطبيقك هناك.

أخيرًا وليس آخرًا ، مع وجود LINQ في C# 3.5 ، يمكنك الانضمام إلى هؤلاء معًا مثل Greg Beech فقط هنا ، ولكن بدلاً من استخدام string.join () الاستخدام:

StringBuilder sb = new StringBuilder();
foreach (var item in values) {
  sb.Append(item);
  sb.Append(" ");
}

أتمنى أن يساعدك هذا.

أوصي بالتجاوز طريقة tostring ، وأخذ تطبيق iformatprovider الذي يحدد الأنواع المخصصة الخاصة بك.

انظر MSDN في http://msdn.microsoft.com/en-us/library/system.iformatprovider.aspx للحصول على معلومات حول تنفيذ iformatprovider.

يمكنك بعد ذلك رمز مثل هذا:
address.ToString ("S") ؛ // عنوان قصير
address.ToString ("أي شيء") ؛ // أيا كان التنسيق المخصص الذي تحدده.

بالتأكيد ليست أسهل طريقة للقيام بذلك ، ولكن أنظف IMHO. مثال على هذا التنفيذ هو فئة DateTime.

هتافات
رماد

أولاً ، يتطلب العنوان معلومات معينة ، لذلك يجب ألا تسمح لعنوان لا يحتوي على رمز الرمز البريدي على سبيل المثال. يمكنك أيضًا التأكد من عدم وجودها أبدًا عن طريق تهيئة كل خاصية إلى سلسلة فارغة ، أو عن طريق مطالبة كل خاصية كوسائط إلى المنشئ. وبهذه الطريقة ، أنت تعلم أنك تتعامل مع بيانات صالحة بالفعل ، بحيث يمكنك فقط إخراج سلسلة منسقة دون حاجة لشيكات isNullorEmpty.

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

إذا لم تكن بياناتك موثوقة تمامًا ، فستحتاج إلى هذا المنطق في مكان ما - أقترح أن تقوم بإنشاء خاصية أخرى للقراءة فقط (نسميها شيئًا مثل FormattedAddress) الذي يقوم بهذا المنطق بالنسبة لك. وبهذه الطريقة ، ليس عليك تغيير أي من التعليمات البرمجية ، في مرحلة ما ، تقوم بتنظيف القواعد أو تغييرها بطريقة أخرى.

و +1 للاقتراح لاستخدام stringBuilder ، بدلاً من السلاسل المتسلسلة.

أعلم أن هذا قديم حقًا ، لكنني شعرت بحل عام ونفذت الألغام بهذه الطريقة:

private static string GetFormattedAddress(
    string address1,
    string address2,
    string city,
    string state,
    string zip)
{
    var addressItems =
        new []
        {
            new[] { address1, "\n" },
            new[] { address2, "\n" },
            new[] { city, ", " },
            new[] { state, " " },
            new[] { zip, null }
        };

    string suffix = null;
    var sb = new StringBuilder(128);

    foreach (var item in addressItems)
    {
        if (!string.IsNullOrWhiteSpace(item[0]))
        {
            // Append the last item's suffix
            sb.Append(suffix);

            // Append the address component
            sb.Append(item[0]);

            // Cache the suffix
            suffix = item[1];
        }
    }

    return sb.ToString();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top