2012-01-08 5 views
4

j'ai un problème litte et j'ai besoin d'aide :)objets génériques en C#

Par exemple, j'ai une classe abstraite simle

public abstract class BaseDefinition 
{ 
    public int Id { get;set; } 
    public string Name { get;set; } 
} 

et d'autres classe de base

public abstract class BaseParentClass 
{ 
    public string Name { get;set; } 
    public string Schema { get;set; } 
} 

et première classe abstraite générique

public abstrac class BaseParentClass<T> : 
    BaseParentClass where T : BaseDefinition 
{ 
    public IList<T> Objects {get;set;} 
} 

et premières implémentations

public class ClassADefintion : BaseDefinition 
{ 
    public bool IsChanged {get;set;} 
} 


public class ClassAObject : BaseParentClass<ClassADefinition> 
{ 
    public bool OtherField {get;set;} 
} 

public class ClassBDefintion : BaseDefinition 
{ 
    public bool IsBBBChanged {get;set;} 
} 

public class ClassBObject : BaseParentClass<ClassBDefinition> 
{ 
    public bool OtherBBBBField {get;set;} 
} 

Désolé pour le nom de la classe, mais je ne peux pas créer quelque chose de mieux (il est par exemple seulement) Comme on le voit, est maintenant tout :) OK.

J'ai quelques méthodes qui retourne un IEnumerable de mise en œuvre générique

IEnumerable<ClassBObject> ClassBObjectCollection; 
IEnumerable<ClassAObject> ClassAObjectCollection; 

Maintenant, je dois créer une méthode, qui peut prendre des objets génériques IEnumerable

public void DoWork(IEnumerable<BaseParentClass<BaseDefinition>> objects) 
{ 
    foreach(var baseObj in objects) 
    { 
     foreach(var baseDef in baseObj.Objects) 
     { 
      // do some work 
     } 
    } 
} 

Comment je me souviens BaseObject<BaseDefinition> != ClassAObject, mais Le compilateur ne met aucune erreur sur l'écran. Je me souviens dans .NET dans l'interface générique Nous pouvons utiliser IN et OUT T, donc j'essaie faire ce

public interface IBaseParentClass<out T> where T : BaseDefinition 
{ 
    IList<T> Objects {get;set;} 
} 

Eh oui, vous ne pouvez pas faire une liste des <out T>. Quelqu'un a une idée de ce problème?

Je peux obtenir ces valeurs de champs par réflexion, mais j'ai une classe abstraite et une interface donc je pense que c'est une meilleure façon.

Répondre

2

Je n'ai pas un compilateur à portée de main, mais je pense qu'il devrait être possible de réécrire DoWork en tant que tel:

public void DoWork<T>(IEnumerable<BaseObject<T>> objects) 
    where T : BaseDefinition 
{ 
    foreach(var baseObj in objects) 
    { 
     foreach(var baseDef in baseObj.Objects) 
     { 
      // do some work 
     } 
    } 
} 

Je ne suis pas sûr que le compilateur sera en mesure de déduire T pour vous, Essaye le.

Une autre possibilité peut être que si vous énumérez ces objets de toute façon, pour faire des objets de type IEnumerable (Of T).

+3

http://ideone.com/ fournit un compilateur toujours à portée de main. – millimoose

+0

Fonctionne très bien. C'est simple et je me demande comment je ne peux pas penser à la méthode générique: o MERCI :) – user1091406

+0

@Inerdial nice! – flq