IList <IClient>method <T>(), где T: Iclient не может добавить объект клиента в список - PullRequest
2 голосов
/ 14 апреля 2009

общедоступный IList GetClientsByListofID (идентификаторы IList), где T: IClient { Клиенты IList = новый список (); клиенты.Добавить (новый клиент (3)); }

Я получаю ошибку компилятора здесь:

не может конвертировать из 'Bailey.Objects.Client' в 'T'

Клиентский объект реализует интерфейс IClient. Моя цель здесь состоит в том, чтобы попытаться ослабить связь между моими классами (изучение DI вещи атм). Я думал, что могу сказать, что он может использовать любой тип клиентского объекта, и это будет возвращено.

Я совершенно не в базе?

Спасибо

Джон Хокинс

Ответы [ 5 ]

5 голосов
/ 14 апреля 2009

Вы не можете использовать общие ограничения таким образом. Как компилятор может гарантировать, что параметр типа является 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));
    // ...
}
1 голос
/ 14 апреля 2009

Ваша проблема не в ограничении

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));

Причина, по которой вы не можете сделать то, что вы пытаетесь сделать, заключается в том, что компилятор не может гарантировать, что тип T будет иметь тип Client, поэтому он дает вам ошибку компилятора. Это не имеет ничего общего с вашим ограничением на самом деле.

1 голос
/ 14 апреля 2009

Попробуйте это:

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 );
1 голос
/ 14 апреля 2009

Client является IClient. T является IClient.

Где вы указали, что T это Client? Нигде нет!

Я думаю, вам нужен IClientFactory или IClientRepository, который будет создавать / извлекать экземпляры IClient для вас. После этого вы сможете использовать различные реализации этой фабрики / репозитория.

0 голосов
/ 14 апреля 2009

То, что вы делаете, не работает, потому что в C # 3.0 дженерики не поддерживают ковариацию.

Вы могли бы сделать что-то вроде этого:

    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;
    }

... но мне интересно, нужны ли вам вообще дженерики.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...