iilist الطريقة () حيث t: iclient لا يمكن إضافة كائن العميل إلى القائمة

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

سؤال

Ilist GetClientSyListOfID (ILIST IDS) حيث T: Iclient {ilist العملاء = قائمة جديدة ()؛ عملاء .ADD (عميل جديد (3))؛ }

أحصل على خطأ مترجم هنا:

لا يمكن تحويل من "bailey.Objects.client" إلى 't'

كائن العميل ينفذ واجهة ICLIENT. هدفي هنا هو محاولة تخفيف الاقتران بين فصولي (تعلم أجهزة الصراف الآلي DI كنت أفكر في أنني أستطيع أن أقول أنه يمكن استخدام أي نوع من كائن العميل وسيتم إرجاع ذلك.

هل أنا تماما قبالة قاعدة هنا؟

شكرا

جون هوكينز

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

المحلول

لا يمكنك استخدام قيود عامة بهذه الطريقة. كيف يمكن للمترجم أن يضمن أن المعلمة النوع هي Client ببساطة لأنه ينفذ IClient واجهه المستخدم؟ لا يمكن أن العديد من الأنواع تنفذ تلك الواجهة؟

في هذه الحالة (وهذا في حالة حيث تحتاج إلى العمل مع النوع، وليس الواجهة) من الأفضل تقييد المعلمة النوع مع النوع نفسه مثل هذا:

public IList<T> GetClientsByListofID<T>(IList<int> ids) where T : Client
{
    IList<T> clients = new List<T>();
    clients.Add(new Client(3));
    // ...
}

وبمجرد القيام بذلك أتساءل عما إذا كنت بحاجة إلى طريقة عامة على الإطلاق:

public IList<Client> GetClientsByListofID(IList<int> ids)
{
    IList<Client> clients = new List<Client>();
    clients.Add(new Client(3));
    // ...
}

نصائح أخرى

Client هو IClient. T هو IClient.

أين حددت ذلك T هو Clientب في أي مكان!

أعتقد أنك بحاجة إلى IClientFactory أو IClientRepository سيؤدي ذلك إلى إنشاء / استرجاع مثيلات iClient لك. ستتمكن بعد ذلك من استخدام تطبيقات مختلفة لهذا المصنع / مستودع.

جرب هذا:

public interface IClient
{
    string Name { get; }
}

public class Client : IClient
{
    public string Name { get; set; }
}

     ...

public IList<T> GetClientsByListofID<T>( IList<int> ids )
         where T : class, IClient
{
    var clients = new List<T>();
    var client = new Client { Name = "bob" } as T;

    clients.Add( client );

    return clients;
}

الاستعمال:

     var clients = this.GetClientsByListOfID<Client>( null );

مشكلتك ليست في القيد

where T : IClient

ولكن في استخدام قائمتك.

لا يمكنك أن تقول هذا:

IList<T> clients = new List<T>();
clients.Add( new Client(3));

يمكنك أن تقول هذا: (هذا يفترض أن القيد يتضمن "جديد")

IList<T> clients = new List<T>();
clients.Add( new T());

في هذه الحالة، يجب أن يكون القيد الخاص بك:

    where T : new(), IClient

أو يمكنك القيام بذلك ولكنها لن تستخدم الأجداد على الإطلاق:

IList<T> clients = new List<Client>();
clients.Add( new Client(3));

السبب في أنه لا يمكنك فعل ما تحاول القيام به هو أن التحويل البرمجي لا يمكن أن يكون Gaureantee أن النوع T سيكون من عميل النوع، وهذا هو السبب في أنه يمنحك خطأ التحويل البرمجي. ليس لديها أي شيء للقيام به مع القيد الخاص بك حقا.

ما تفعله لا يعمل لأنه في C # 3.0 Generics لا يدعم التباين.

يمكنك أن تفعل شيئا مثل هذا:

    interface IClient
    {
        int Id { get; set; }
    }

    class Client : IClient
    {
        public int Id { get; set; }
        public Client() { }
    }

    // ...

    public IList<T> GetClientsByListofID<T>(IList<int> ids) where T : IClient, new()
    {
        IList<T> clients = new List<T>();
        clients.Add(new T() { Id = 3 });
        // ...
        return clients;
    }

... لكنني أتساءل عما إذا كنت بحاجة إلى الأجداد على الإطلاق.

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