Question

publics IList GetClientsByListofID (ids IList) où T: iClient     {         clients IList = new List ();         clients.Add (nouveau client (3));     }

Je reçois une erreur de compilation ici:

ne peut pas convertir 'Bailey.Objects.Client' 'T'

L'objet client implémente l'interface iClient. Mon but ici est d'essayer et desserrer le couplage entre mes classes (apprentissage des choses DI atm). Je pensais que je peux dire qu'il peut utiliser tout type d'objet client et qui serait retourné.

Suis-je complètement à côté ici?

Merci

Hawkins Jon

Était-ce utile?

La solution

Vous ne pouvez pas utiliser des contraintes génériques de cette façon. Comment le compilateur peut garantir que le paramètre de type est un Client simplement parce qu'il implémente l'interface IClient? Impossible de nombreux types mettre en œuvre cette interface?

Dans ce cas ( qui est dans le cas où vous devez travailler avec le type, pas l'interface ), il est préférable de limiter le paramètre de type avec le type se présente comme suit:

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

et une fois que je fait me demande si vous avez besoin d'une méthode générique du tout:

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

Autres conseils

Client est un IClient. T est un IClient.

Où avez-vous préciser que T est un Client? Nulle part!

Je pense que vous avez besoin d'un IClientFactory ou IClientRepository qui va créer / récupérer des instances de iClient pour vous. Vous serez alors en mesure d'utiliser différentes implémentations de cette usine / dépôt.

Essayez ceci:

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

Utilisation:

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

Votre problème n'est pas dans la contrainte

where T : IClient

mais plutôt dans l'utilisation de votre liste.

Vous ne pouvez pas dire:

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

vous pouvez dire ceci: (cela suppose que votre contrainte comprend « nouvelle »)

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

dans ce cas, votre contrainte devrait alors être:

    where T : new(), IClient

ou vous pouvez le faire, mais il ne serait pas utiliser les médicaments génériques du tout:

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

La raison pour laquelle vous ne pouvez pas faire ce que vous essayez de faire est parce que le compilateur ne peut pas gaurantee que le type T sera de type client, ce qui est pourquoi il te donne l'erreur du compilateur. Il n'a rien à voir avec votre contrainte vraiment.

ce que vous faites ne fonctionne pas parce que dans C # 3.0 génériques ne prennent pas en charge covariance.

Vous pouvez faire quelque chose comme ceci:

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

... mais je me demande si vous avez besoin génériques du tout.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top