هل هناك طريقة للادلاء القوائم العامة لقوائم لأنواع فئة واجهة / القاعدة؟

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

  •  06-07-2019
  •  | 
  •  

سؤال

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

void PrintProperties(IEnumerable<ISpecialProperties> list)
{
    foreach (var item in list)
    {
        Console.WriteLine("{0} {1}", item.Prop1, item.Prop2);
    }
}

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

using System;
using System.Collections.Generic;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Test> myList = new List<Test>();
            for (int i = 0; i < 5; i++)
            {
                myList.Add(new Test());
            }

            PrintList((IEnumerable<IDoSomething>)myList);
        }

        static void PrintList(IEnumerable<IDoSomething> list)
        {
            foreach (IDoSomething item in list)
            {
                item.DoSomething();
            }
        }
    }

    interface IDoSomething
    {
        void DoSomething();
    }

    public class Test : IDoSomething
    {
        public void DoSomething()
        {
            Console.WriteLine("Test did it!");
        }
    }
}

أنا <م> يمكن استخدام عضو Enumerable.Cast<T> للقيام بذلك، ولكن كنت تبحث عن الطريقة التي يمكن أن تعمل في. NET 2.0 كذلك. يبدو مثل هذا ينبغي أن يكون ممكنا. ماذا ينقصني؟

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

المحلول

والمشكلة هي مع أسلوب، وليس مع كيف يطلق عليه .....

void PrintProperties<SP>(IEnumerable<SP> list) where SP: ISpecialProperties
{
    foreach (var item in list)
    {
        Console.WriteLine("{0} {1}", item.Prop1, item.Prop2);
    }
}

نصائح أخرى

والسبب أنه فشل لأن الأدوية لا يحمل التباين في C # (حتى الآن).

وأما بالنسبة للإصلاح IEnumerable ، ومع ذلك، حاول هذا:

public static IEnumerable<TBase> SafeConvert<TBase, TDerived>(IEnumerable<TDerived> source)
    where TDerived : TBase
{
    foreach (TDerived element in source)
    {
        yield return element; // Implicit conversion to TBase
    }
}

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

ويمكنك فقط استخدام foreach على القوائم لديك. وforeach يفعل بنيت في المدلى بها. لذلك إذا كنت تأخذ الحلقة من وظيفة يمكنك كتابة شيء من هذا القبيل

List<Test> myList = new List<Test>();
for (int i = 0; i < 5; i++)
{
   myList.Add(new Test());
}

foreach (IDoSomething item in myList)
{
   item.DoSomething();
}

وماذا تريد يسمى "التغاير واجهة" وغير معتمد من قبل C # في الوقت الراهن. يمكنك أن تقرأ عن ذلك على بلوق اريك ليبرت و.

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

scroll top