iilist الطريقة () حيث t: iclient لا يمكن إضافة كائن العميل إلى القائمة
-
09-09-2019 - |
سؤال
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;
}
... لكنني أتساءل عما إذا كنت بحاجة إلى الأجداد على الإطلاق.