C # Доступ к свойствам универсального объекта - PullRequest
9 голосов
/ 21 мая 2010

У меня есть метод, который подсчитывает количество контактов каждого Поставщика, Клиента и Производителя (это сценарий, чтобы попытаться объяснить проще!)

Все модели создаются классами Linq to SQL. Каждый поставщик, клиент и производитель может иметь один или несколько контактов

public int CountContacts<TModel>(TModel entity) where TModel : class
{
    return entity.Contacts.Count();
}

Вышеуказанное, конечно, не работает, потому что «сущность» является универсальной и не знает, имеет ли она свойство «Контакты». Может кто-нибудь помочь с тем, как этого добиться?

Ответы [ 5 ]

6 голосов
/ 21 мая 2010

Простым способом было бы присоединить интерфейс к классам, реализуемым в шаблоне.

public int CountContacts<TModel>(TModel entity) where TModel : IContacts


interface IContacts
{
   IList<Contact> Contacts {get;} //list,Ilist,ienumerable
}
3 голосов
/ 21 мая 2010

Один из способов навязывания контракта , при котором поставщики, клиенты и производители должны содержать свойство Contacts, - это интерфейсы. Сделайте так, чтобы каждая сущность реализовала один интерфейс, содержащий свойство Contacts:

interface IContactable
{
   IEnumerable<Contact> Contacts {get;}
}


public int CountContacts<TModel>(TModel entity) where TModel : class, IContactable
{
    return entity.Contacts.Count();
}
1 голос
/ 21 мая 2010

Все ответы до сих пор верны, но следует также указать, что причина, по которой ваш код не компилируется, состоит в том, что типы TModel не имеют ничего общего.Указав общий базовый класс или интерфейс, все они реализуют с помощью свойства «Контакты», ваш код будет работать.

0 голосов
/ 21 мая 2010

Существует несколько решений проблемы.

  • Унаследуйте один и тот же абстрактный класс или реализуйте один и тот же интерфейс с сущностями.(Другие исчерпали каждое возможное решение этим.)
  • Если вы используете .NET 4, ключевое слово dynamic может быть самым дешевым решением.

Например:

public int CountContacts(dynamic entity)
{
    return entity.Contacts.Count();
}

Это означает, что entity не будет оцениваться до времени выполнения, и если вам случится вызвать метод для объекта, у которого нет свойства Contacts, он выдаст вам исключение.

0 голосов
/ 21 мая 2010

Другой способ - создать интерфейс только для подсчета. Вы можете назвать это 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; }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...