У меня есть метод, который считает количество Контактов, которые каждый Поставщик, Клиент и Производитель имеют (это - сценарий для попытки, делают объяснение легче!)
Модели все создаются Linq к классам SQL. У каждого Поставщика, Клиента и Производителя может быть один или несколько Контактов
public int CountContacts<TModel>(TModel entity) where TModel : class
{
return entity.Contacts.Count();
}
Вышеупомянутое, конечно, не работает, потому что 'объект' универсален и не знает, имеет ли это свойство 'Contacts'. Кто-то может помочь с тем, как достигнуть этого?
Простым способом было бы присоединить интерфейс к классам, реализованным в универсальном.
public int CountContacts<TModel>(TModel entity) where TModel : IContacts
interface IContacts
{
IList<Contact> Contacts {get;} //list,Ilist,ienumerable
}
Есть несколько вариантов решения проблемы.
dynamic
может быть самым дешевым решением. Например:
public int CountContacts(dynamic entity)
{
return entity.Contacts.Count();
}
Это означает, что объект
не будет оцениваться до времени выполнения, и если вы случайно вызовете метод для объекта, у которого нет контактов
свойство, это вызовет исключение.
Все ответы на данный момент верны, но также следует указать, что причина того, что ваш код не компилируется, заключается в том, что типы TModel не имеют ничего общего. Указав общий базовый класс или интерфейс, который они все реализуют с вашим свойством «Контакты», ваш код будет работать.
Один из способов навязать контракт , в котором Поставщики, Заказчики и Производители должны содержать свойство Контакты
, - это интерфейсы. Сделайте так, чтобы каждая сущность реализовывала один интерфейс, который содержит свойство Контакты
:
interface IContactable
{
IEnumerable<Contact> Contacts {get;}
}
public int CountContacts<TModel>(TModel entity) where TModel : class, IContactable
{
return entity.Contacts.Count();
}
Другой способ - создать интерфейс только для подсчета. Вы можете назвать это ICountable.
Из MSDN
public interface ICountable<out T>
{
int Count{ get; }
}
public class MyCollection : ICountable<string>, ICountable<FileStream>
{
int ICountable<string>.Count
{
get { return 1; }
}
int ICountable<FileStream>.Count
{
get { return 2; }
}
}