2009-07-10 8 views
1

Je reçois l'erreur "T ne contient pas une définition pour Id" ci-dessous dans la ligne spécifiée, même si je débogue, je vois que "article" a en effet a une propriété "Id" dans son classe de base.Comment indiquer à C# de regarder dans la classe de base d'un objet pour une propriété?

Comment puis-je spécifier ici que je veux que C# regarde dans la classe de base de l'élément pour Id (et pourquoi ne le fait-il pas automatiquement?)?

//public abstract class Items<T> : ItemBase (causes same error) 
public abstract class Items<T> where T : ItemBase 
{ 
    public List<T> _collection = new List<T>(); 
    public List<T> Collection 
    { 
     get 
     { 
      return _collection; 
     } 
    } 

    public int GetNextId() 
    { 
     int highestId = 0; 
     foreach (T item in _collection) 
     { 
      //ERROR: "T does not contain a definition for Id 
      if (item.Id > highestId) highestId = item.Id; 
     } 

     return highestId; 
    } 

} 

Voilà comment les classes sont définies:

public class SmartForm : Item 
{ 
    public string IdCode { get; set; } 
    public string Title { get; set; } 
    public string Description { get; set; } 
    public int LabelWidth { get; set; } 
    public int FormWidth { get; set; } 
    ... 


public abstract class Item : ItemBase 
{ 
    public int Id { get; set; } 
    public DateTime WhenCreated { get; set; } 
    public string ItemOwner { get; set; } 
    public string PublishStatus { get; set; } 
    public int CorrectionOfId { get; set; } 
    ... 
+0

Quelle est la définition de Id dans ItemBase? On dirait que c'est privé –

+0

Quelle est la définition de ItemBase? – cjk

Répondre

12

Votre problème est qu'il n'y a pas de contrainte sur T, donc, à la compilation ti moi, tout le compilateur sait que T est une sorte d'objet. Si vous savez quel type T sera toujours hériter de, vous pouvez ajouter une contrainte générique à la définition de la classe:

public abstract class Items<T> : ItemBase where T : Item 
{ 
//.... 
} 

Lorsque vous le débogage, T est instancié à un élément (ou sous-classe de) qui ne dispose d'une Propriété Id, mais le compilateur ne le sait pas au moment de la compilation, d'où l'erreur.

+0

belle, merci. –

+0

Je ne comprends pas ... pourquoi les éléments héritent-ils de ItemBase? –

+0

Chaque élément de mon application a une classe singulière et plurielle, par exemple. User -> Item -> ItemBase, et Users -> Items -> ItemBase où ItemBase a des méthodes protégées que les classes de modèles au singulier et au pluriel utilisent telles que ApplicationDataPath FullXmlDataStorePathAndFileName et HandleXmlFileNotFound, etc. –

4

Vous avez obtenu votre mal contrainte générique.

public abstract class Items<T> : ItemBase 

devrait être:

public abstract class Items<T> where T : ItemBase 

Qu'est-il arrivé est que si votre classe a une collection d'articles, votre ItemBase est pas associé à T

-1

cela pourrait aider :-)

foreach (ItemBase item in _collection) 
    { 
     if (item.Id > highestId) highestId = (Item)item.Id; 
    } 
+0

si erreur de compilation essayez typecasting à ItemBase –

+0

me dit une "conversation du type T à Itembase" n'est pas possible –

1

Vous devez spécifier que T est toujours dérivé de ItemBase à l'aide d'une clause where.

4

Parce que T peut être absolument n'importe quoi, et C# est censé être de type sécurisé. Utilisez une contrainte sur T pour un type qui a une propriété id, et vous devriez être OK. Voir here pour plus d'informations.

1

Vous avez accidentellement laissé les éléments hériter de ItemBase, au lieu que T hérite de ItemBase. Il suffit de changer

: ItemBase 

à

where T : ItemBase 
+0

J'ai changé "classe abstraite publique Articles : ItemBase" à "classe publique abstraite Articles où T: ItemBase" et j'obtiens la même erreur, a changé le code ci-dessus. –

Questions connexes