سؤال

هل هناك مشكلة في الاستخدام IEnumerable<T> كنوع العودة؟تشكو FxCop من العودة List<T> (وينصح بالعودة Collection<T> بدلاً من).

حسنًا، لقد استرشدت دائمًا بقاعدة "اقبل أقل ما تستطيع، ولكن قم بإرجاع الحد الأقصى".

ومن هذا المنطلق يعود IEnumerable<T> أمر سيء، ولكن ماذا علي أن أفعل عندما أرغب في استخدام "الاسترجاع البطيء"؟أيضا، yield الكلمة الرئيسية هي مثل هذه الأشياء الجيدة.

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

المحلول

وهذا هو حقا سؤال الجزء الثاني.

1) هل هناك أصلا أي شيء خاطئ مع عودته إلى IEnumerable

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

2) هل هناك أي ظرف من الظروف حيث أنه قد يكون من الأفضل للعودة شيء آخر غير IEnumerable

نعم. في حين انها ليست فكرة عظيمة لنفترض الكثير عن المتصلين بك، أنها بخير تماما لاتخاذ القرارات على أساس السلوك الخاصة بك. تخيل سيناريو حيث كان لديك كائن متعددة الخيوط التي تم يصطفون طلبات إلى كائن تم تطويرها باستمرار. في هذه الحالة إرجاع IEnumerable الخام غير مسؤول. حالما يتم تعديل مجموعة من enumerable ينتقض وسوف يسبب execption تحدث. وبدلا من ذلك يمكنك أن تأخذ لقطة من هيكل وتعود تلك القيمة. يقول في شكل قائمة . في هذه الحالة أود فقط العودة الكائن كهيكل المباشر (أو واجهة).

وهذا هو بالتأكيد حالة نادرة بالرغم من ذلك.

نصائح أخرى

لا، IEnumerable<T> هو جيدة شيء للعودة هنا، لأن كل ما يعدون هو "تسلسل (المكتوبة) القيم". مثالية للLINQ غيرها، ويمكن استخدامها تماما.

والمتصل يمكن بسهولة وضع هذه البيانات في قائمة (أو أيا كان) - خصوصا مع LINQ (ToList، ToArray، الخ)

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

وعن المبدأ الخاص بك: "قبول أقل ما يمكن، ولكن العودة الحد الأقصى"

والمفتاح لإدارة تعقيد برنامج كبير هو تقنية تسمى <م> معلومات يختبئ . إذا كان يعمل الأسلوب الخاص بك عن طريق بناء List<T>، انها ليست في كثير من الأحيان من الضروري كشف هذه الحقيقة من خلال إعادة هذا النوع. إذا قمت بذلك، ثم المتصلين بك قد تعديل قائمة يعودون. هذا يزيل قدرتك على القيام التخزين المؤقت، أو التكرار كسول مع yield return.

وهكذا مبدأ أفضل هو وظيفة لمتابعة هي: "الكشف عن أقل قدر ممكن من المعلومات عن كيفية عمل"

وIEnumerable على ما يرام من قبلي ولكن له بعض العيوب. لدى العميل لتعداد للحصول على النتائج. كان لديه أي وسيلة للتحقق من عدد الخ قائمة سيئة لأنك فضح الكثير من السيطرة؛ يمكن للعميل إضافة / إزالة الخ منه والتي يمكن أن تكون أمرا سيئا. جمع يبدو أفضل compromomise، على الأقل من وجهة FxCop ل. I لل Allways استخدام ما يبدو appropiate في سياق بلدي (على سبيل المثال إذا أريد للعودة للقراءة فقط جمع ط فضح جمع كنوع العودة والعودة List.AsReadOnly () أو IEnumerable لتقييم كسول من خلال العائد الخ). أعتبر على كل حالة على حدة

"اقبل أقل ما تستطيع، ولكن رد الحد الأقصى" هو ما أؤيده.عندما تقوم إحدى الطرق بإرجاع كائن، ما هي المبررات التي لدينا لعدم إرجاع النوع الفعلي والحد من قدرات الكائن عن طريق إرجاع نوع أساسي.لكن هذا يثير سؤالاً كيف نعرف ما هو "الحد الأقصى" (النوع الفعلي) عندما نقوم بتصميم واجهة.الجواب بسيط جدا.فقط في الحالات القصوى حيث يقوم مصمم الواجهة بتصميم واجهة مفتوحة، والتي سيتم تنفيذها خارج التطبيق/المكون، فلن يعرفوا نوع الإرجاع الفعلي.يجب على المصمم الذكي أن يفكر دائمًا في ما يجب أن تفعله الطريقة وما يجب أن يكون عليه نوع الإرجاع الأمثل/العام.

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

ما قيل أعلاه، هناك بعض الأشياء الأخرى التي يجب مراعاتها

  • إذا كانت البيانات التي تم إرجاعها يجب أن تكون قابلة للتغيير أو غير قابلة للتغيير

  • إذا تمت مشاركة البيانات التي تم إرجاعها عبر عدة متصلين

فيما يتعلق بتقييمات LINQ البطيئة، أنا متأكد من أن 95%+ من مستخدمي C# لا يفهمون النزاهة.إنه غير عادي.يشجع OO تغييرات الحالة الملموسة على استدعاءات الطريقة.يعمل تقييم LINQ البطيء على تعزيز تغييرات حالة وقت التشغيل على نمط تقييم التعبير (وهو أمر لا يتبعه المستخدمون غير المتقدمين دائمًا).

وبالعودة IEnumerable على ما يرام إذا كنت حقا فقط عودة سردا، وسوف يستهلك من قبل المتصل بك على هذا النحو.

ولكن كما يشير آخرون إلى أنه لديه عيب أن المتصل قد تحتاج إلى تعداد اذا كان يحتاج الى أي معلومات أخرى (على سبيل المثال عدد). طريقة تمديد الصافي 3.5 سوف IEnumerable .Count تعداد وراء الكواليس إذا كانت قيمة الإرجاع لا يطبق ICollection ، والتي قد تكون غير مرغوب فيها.

وأنا غالبا ما يعود IList أو ICollection عندما تكون النتيجة مجموعة - داخليا طريقتك يمكن استخدام قائمة وإما إعادته كما هو، أو العودة قائمة .AsReadOnly إذا كنت تريد حماية ضد التعديل (على سبيل المثال إذا كنت التخزين المؤقت قائمة داخليا). AFAIK FxCop سعيدة جدا مع أي من هذه.

أحد الجوانب المهمة هو أنه عند إرجاع ملف List<T> أنت عائد فعليًا أ مرجع.وهذا يجعل من الممكن للمتصل التلاعب بقائمتك.هذه مشكلة شائعة — على سبيل المثال، طبقة الأعمال التي تُرجع ملفًا List<T> إلى طبقة واجهة المستخدم الرسومية.

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

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

وأنا لا يمكن أن تقبل الجواب الذي تم اختياره. هناك طرق للتعامل مع سيناريو وصفه ولكن باستخدام قائمة أو أي شيء آخر باستخدام ليست واحدة منها. يتم إرجاع لحظة IEnumerable لديك لنفترض أن المتصل قد تفعل foreach. في هذه الحالة لا يهم إذا كان نوع ملموس قائمة أو معكرونة. في الواقع الفهرسة مجرد مشكلة خاصة إذا تم إزالة العناصر.

وأي القيمة التي تم إرجاعها لقطة. قد يكون من المحتويات الحالية من IEnumerable في هذه الحالة إذا المخبأة أنه ينبغي أن يكون نسخة من النسخة المخبأة. إذا كان من المفترض أن تكون أكثر ديناميكية (مثل resuts استعلام SQL) ثم استخدام العائد العائد. ومع ذلك يسمح الحاوية لتتحول في الإرادة وتوفير أساليب مثل عدد ومفهرس هو وصفة لكارثة في عالم مؤشرات. أنا لم حتى وصلت إلى قدرة الطالب على استدعاء إضافة أو حذف في وعاء من المفترض أن يكون في السيطرة على التعليمات البرمجية.

وأيضا إرجاع أقفال نوع ملموسة لكم في التنفيذ. اليوم داخليا قد تكون تستخدم قائمة. غدا ربما لم تصبح مؤشرات وتريد استخدام وعاء موضوع آمنة أو مجموعة أو طابور أو جمع القيم من قاموس أو إخراج استعلام ينق. إذا كنت قفل نفسك في نوع الإرجاع ملموس ثم عليك إما تغيير مجموعة من الرموز أو القيام التحويلات قبل أن يعود.

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