Le code suivant me donne cette erreur:
ne peut pas convertir de 'System.Collections.Generic.List' à 'System.Collections.Generic.List'. P> blockQuote>
Comment puis-je indiquer au compilateur que le client hérite effectivement de l'objet? strong> ou est-ce que cela ne fait-il pas de l'héritage avec des objets de collecte génériques (envoi d'une liste < / code> obtient la même erreur). p> xxx pré> p>
8 Réponses :
C # (à l'heure actuelle) ne prend pas en charge la variance pour les types génériques.
Cependant, si vous utilisez C # 3.0, vous pouvez le faire: P>
FillSmartGrid( customers.Cast<object>() );
+1 pour cela. Si vous êtes pré-version-3, vous pouvez écrire une méthode pour convertir la liste
.NET n'a pas de co-variance et de contre-variance (encore). P>
que b dérive d'un problème n'implique pas que .NET 4.0 obtiendra la co-variance et la contre-variance limitées. P> list code> dérive de list code>. Ce n'est pas le cas. Ils sont deux types totalement différents. P>
Je ne pense pas que la covariance dans .NET 4 aidera dans cette situation.
@Mark Byers: Pourquoi? On dirait que ça devrait aider beaucoup
@Mark est correct. Le soutien de la covariance ajouté à C # est limité aux interfaces et aux délégués. La liste
Il n'y a pas de covariance pour les listes, car ce n'est ni "dans" ni "sorti"
Voir aussi: Marcgravell.blogspot.com/2009 / 02 / ...
Et en fait, le CLI fait I> AVEZ CELA - C # I> n'est pas, à l'exception des tableaux.
J'ai peut-être tiré de ma réponse un peu trop tôt. Devrais-je supprimer ou éditer mon message?
C'est le problème de la covariance et ce n'est pas aussi facile que cela semble à première vue. C # 4 aura un certain soutien à cela. P>
Pour obtenir l'idée des problèmes, imaginez dans votre cas que cette distribution fonctionnerait réellement. Maintenant, vous avez une liste Malheureusement, certains problèmes auraient pu être résolus en utilisant une conception intelligente (ER) des interfaces avec des méthodes génériques où la covariance est correcte, telle que pour Getenumerator. P> add code> doit être un client code>, de sorte que cela viole clairement la mise en œuvre; La mise en œuvre ne fournit pas la méthode add (objet obj) code>. p>
C'est parce qu'une liste d'une classe n'est pas convertible vers une liste de la classe de base. C'est une décision délibérée de faire la sécurité de la langue. Cette question se pose souvent.
Ici est ma réponse standard de la manière de contourner le problème: p> ou: p> List<A> listOfA = new List<C>().Cast<A>().ToList();
Ceci a été couvert Ad-Nauseum dans de nombreuses autres réponses. La réponse courte est la suivante:
considère que j'ai ces variables: p> maintenant, voici là qu'il arrête de compiler: P> objects = customers; // sounds OK, since a Customer is an object, right?
objects.Add("foo");
au lieu de la liste de réussite qui ne fonctionne pas pour les raisons ci-dessus, pourriez-vous ne pas simplement passer simplement une référence d'objet, puis obtenir le type de liste après, un peu comme ...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1 {
class Customer {
public int id;
public string name;
}
class Monkey {
public void AcceptsObject(object list) {
if (list is List<Customer>) {
List<Customer> customerlist = list as List<Customer>;
foreach (Customer c in customerlist) {
Console.WriteLine(c.name);
}
}
}
}
class Program {
static void Main(string[] args) {
Monkey monkey = new Monkey();
List<Customer> customers = new List<Customer> { new Customer() { id = 1, name = "Fred" } };
monkey.AcceptsObject(customers);
Console.ReadLine();
}
}
}
Pourquoi le paramètre ne peut-il pas être de type IList? p>
Public Void FillsMartGrid (iList Articles) P>
Je suis d'accord avec la réponse de Winston Smith.
Je voulais juste souligner comme une alternative (bien que cela n'ait éventuellement pas le meilleur moyen de gérer la situation) que, lors de la liste Par conséquent, il est possible de le faire: P> list {
List<Customer> customers = new List<Customer>();
// ...
FillSmartGrid(customers.ToArray());
// ...
}
public void FillSmartGrid(object[] items)
{
}
Pourquoi prenez-vous la liste articles?
de faire une réflexion sur eux et les traiter dynamiquement
Vous pouvez toujours effectuer une réflexion sur un objet code> code> comme vous pouvez sur un objet
code>.Je vais envoyer des collections d'autres objets autres que le client, j'ai corrigé le code un peu pour refléter cela.
Ne pas répondre à votre question mais résoudre probablement votre problème :) Public Void FillsMartGrid (Liste Articles) pourrait être réécrit à: Public Void Fillsmartgrid (liste articles). Le compilateur déterminera ce que T est tellement vous n'avez pas besoin de le fournir et que vous faites simplement une réflexion dans le corps de la méthode qui devrait fonctionner pour tous vos types.
@Runefs +1 pour votre commentaire, résolu mon problème.