سؤال

في رد على هذا السؤال runefs وأشار إلى أن "ما لم يكن لديك سبب محدد باستخدام IList يجب أن considere IEnumerable".التي تستخدمها و لماذا ؟

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

المحلول

IEnumberable<T> للقراءة فقط، عليك إعادة بناء المجموعة لإجراء تغييرات عليه. من ناحية أخرى، IList<T> هو قراءة الكتابة. لذلك إذا كنت تتوقع الكثير من التغييرات في المجموعة، ففي IList<T> ولكن إذا كان من الآمن افتراض أنك لن تعدلها، فانتقل IEnumerable<T>.

نصائح أخرى

دائما استخدام الأكثر تقييدا واجهة التي توفر الميزات التي تحتاج إليها ، لأن ذلك يعطي لك أكثر مرونة لتغيير التنفيذ في وقت لاحق.لذا ، إذا IEnumerable<T> هو بما فيه الكفاية ، ثم استخدام هذا...إذا كنت بحاجة إلى قائمة ميزات استخدام IList<T>.

ويفضل استخدام بقوة كتبته إصدارات عامة.

مبدأ أتابع هو قرأتها مرة أخرى:

"تستهلك أبسط و فضح الأكثر تعقيدا"

(أنا متأكد من أن هذا هو حقا المشتركة و انا mis-نقلا عن ذلك ، إذا كان أي شخص يمكن أن يعرف مصدر يمكنك ترك تعليق أو تحرير من فضلك...)

(تحرير لإضافة - حسنا ، أنا هنا بضعة أسابيع في وقت لاحق و لقد واجهت هذا الاقتباس في سياق مختلف تماما ، يبدو أنه بدأ في متانة مبدأ أو Postel القانون -

يكون المحافظ في ما يمكنك القيام به ؛ أن الليبرالية في ما يقبل من الآخرين.

التعريف الأصلي هو شبكة الاتصالات عبر الإنترنت, ولكن أنا متأكد من أني قد رأيت ذلك أغراض أخرى تحديد فئة عقود OO.)

في الأساس, إذا كنت تحديد طريقة للاستهلاك الخارجي ثم المعلمات يجب أن تكون أبسط من النوع الذي يمنحك وظيفة تحتاج - في حالة المثال الخاص بك وهذا قد يعني أخذ في IEnumerable بدلا من IList.وهذا يعطي العميل رمز الأكثر مرونة أكثر ما يمكن أن تمر.من ناحية أخرى إذا كنت تعريض الممتلكات للاستهلاك الخارجي ثم القيام بذلك مع الأكثر تعقيدا نوع (IList أو ICollection بدلا من IEnumerable) لأن هذا يعطي العميل الأكثر مرونة في طريقة استخدام الكائن.


أنا وجدت المحادثة بين نفسي و DrJokepu في التعليقات رائعة, ولكن أنا أيضا أقدر أن هذا ليس من المفترض أن يكون منتدى للنقاش لذلك سوف تحرير جوابي على مزيد من مخطط الأسباب وراء قراري لمقاومة هذا الاتجاه و أقترح عليك أن تعرض على أنها IList (حسنا قائمة في الواقع ، كما سترى).دعنا نقول هذا هو الدرجة نحن نتحدث عن:

public class Example
{
    private List<int> _internal = new List<int>();

    public /*To be decided*/ External
    {
        get { return _internal; }
    }
}

لذلك أولا وقبل كل دعونا نفترض أننا تعريض الخارجية باعتبارها IEnumerable.الأسباب رأيت للقيام بذلك في إجابات أخرى و تعليقات حاليا:

  • IEnumerable للقراءة فقط
  • IEnumerable هو الفعلية قياسي
  • فإنه يقلل من اقتران حتى تتمكن من تغيير التنفيذ
  • لا تعرض تفاصيل التنفيذ

في حين IEnumerable فقط يعرض للقراءة فقط الوظائف التي لا تجعل للقراءة فقط.نوع حقيقي لما هو العثور بسهولة من خلال التفكير أو ببساطة التوقف مصحح و البحث ، لذا فمن تافهة ليلقي عليه العودة إلى القائمة<>, ونفس الشيء ينطبق على FileStream سبيل المثال في التعليقات أدناه.إذا كنت تحاول حماية الأعضاء ثم التظاهر هو شيء آخر ليس من طريقة للقيام بذلك.

أنا لا أعتقد أنه هو الفعلية قياسي.أنا لا يمكن العثور على أي رمز في .NET framework 3.5 المكتبة حيث مايكروسوفت خيار العودة غير ملموسة جمع وعاد واجهة بدلا من ذلك.IEnumerable هو أكثر شيوعا في 3.5 بفضل LINQ, ولكن هذا هو لأنهم لا يستطيعون فضح أكثر نوع مشتق ، ليس لأنهم لا يريدون.

الآن الحد من اقتران أنا أتفق مع - إلى حد ما - في الأساس يبدو أن هذه الحجة يكون ذلك كنت أقول العميل أنه في حين أن الكائن عودتك هو قائمة أريدك أن علاج مثل IEnumerable فقط في حال كنت ترغب في تغيير رمز الداخلي في وقت لاحق.تجاهل المشاكل مع هذا الواقع نوع يتعرض على أي حال فإنه ما زال يترك السؤال "لماذا نتوقف عند IEnumerable ؟" إذا تعود على أنها نوع الكائن ثم سيكون لديك الحرية الكاملة لتغيير تنفيذ أي شيء!هذا يعني أنه يجب أن يكون قرارا حول كيفية الكثير من الوظائف رمز العميل يتطلب ذلك إما كتابة رمز العميل ، أو قرار حول التعسفي المقاييس.

أخيرا, كما نوقش سابقا, يمكنك أن تفترض أن تنفيذ التفاصيل دائما التي تتعرض لها .صافي, خاصة إذا كنت علنا وفضح الكائن.

حتى بعد هذا الوقت الطويل خطبة لاذعة هناك سؤال واحد اليسرى - لماذا تعرض عليه قائمة<>?حسنا, لماذا لا ؟ لم يحقق أي من خلال تعريض أنها IEnumerable ، فلماذا مصطنع الحد رمز العميل القدرة على العمل مع الكائن ؟ تخيل لو أن مايكروسوفت قد قررت أن الضوابط مجموعة من Winforms التحكم يجب أن تظهر كما IEnumerable بدلا من ControlCollection - أنك لم تعد قادرة على تمرير ذلك إلى الأساليب التي تتطلب IList ، والعمل على البنود في تعسفية مؤشر أو نرى إذا كان يحتوي على عنصر تحكم معين إلا إذا كنت المدلى بها.مايكروسوفت لن اكتسبت أي شيء كان إزعاج لك.

عندما أحتاج فقط إلى تعداد الأطفال، فأنا استخدم iEnumerable. إذا كنت بحاجة إلى العدد، فأنا أستخدم iCollection. أحاول تجنب ذلك، لأنها تعرض تفاصيل التنفيذ.

IList<T> هو في الواقع واجهة سمين جدا. انا افضل اكشف Collection<T>لأنواع كبار السن. هذا يتماشى إلى حد كبير مع ما يقترح جيفري ريختر القيام به (لا تملك كتابا قريبا، لذلك لا يمكن تحديد رقم الصفحة / الفصل): يجب أن تقبل الأساليب أن تقبل الأنواع الأكثر شيوعا كمعلمات وإرجاع معظم أنواع "مشتقة" قيم العودة.

إذا تعرضت مجموعة للقراءة فقط من خلال خاصية، فإن الطريقة التقليدية للقيام بذلك هي اكتشافها كقريبة ReadonlyCollection (أو فئة مشتقة من ذلك) التفاف كل ما لديك هناك. إنه يكشف إمكانات كاملة عن ILIST إلى العميل، ومع ذلك، فإنه يجعل من الواضح جدا أنه للقراءة فقط.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top