2009-07-15 6 views
1

J'essaie de créer une interface générique qui hérite de l'interface System.ICloneable mais où le type de retour de la méthode Clone() est T. Bien sûr, le type T a besoin de contraintes pour être sûr que c'est un héritage de la classe System.Object mais le code suivant ne fonctionne pas.Type de contraintes de contraintes pour le principe de liskov en C# .NET

public interface ICloneable<T> : System.ICloneable where T : object { 

    T Clone(); 

} 

Qu'est-ce que je fais mal?

également les contraintes suivantes ne fonctionnent pas:

  1. où T: System.Object
  2. où T: classe

comment puis-je utiliser le principe Liskov dans ce cas que dit que vous pouvez réduire votre type de retour, pour résoudre ce problème?

P.S .: Désolé pour mon anglais, si j'ai fait des erreurs. Je ne suis pas un locuteur natif anglais.

+1

Pas besoin d'excuser votre anglais, c'est très bien. –

+0

Incidemment, je vous suggère de marquer le type T comme covariant (mettre le mot "out" avant) et aussi d'ajouter une propriété en lecture seule "T self", ou bien définir une interface ISelf en lecture seule propriété "T soi". Notez que T ne devrait pas être contraint à être ICloneable ni ISelf . Si vous faites cela, on peut avoir des classes Foo et DerivedFoo sans méthode clone publique, et des classes CloneableFoo et CloneableDerivedFoo qui en dérivent, et accepter toute dérivée clonable de Foo comme ICloneable , même si ces dérivées clonables ne partagent aucune classe de base commune . – supercat

Répondre

5

Pourquoi avez-vous besoin d'une contrainte? Tout hérite de object ...

Sans la contrainte de votre code devrait fonctionner, mais vous aurez besoin de mettre en œuvre les méthodes Clone de la même manière que IEnumerable/IEnumerable<T> travail - .NET ne pas les types de retour covariants. Vous devez alors également préciser que votre méthode Clone se cache celui ICloneable:

public interface ICloneable<T> : ICloneable 
{ 
    new T Clone(); 
} 

Notez que l'interface ICloneable actuelle est quelque peu obsolète - car il ne donne aucune indication de la profondeur du clonage, il est pas très utile dans la plupart cas.

Avez-vous vraiment besoin d'étendre le type non générique? Pensez-vous que les utilisateurs voudront utiliser l'interface non générique ainsi que votre interface générique?

+0

Je veux une interface donc j'ai besoin d'écrire la méthode Clone() seulement une fois. Donc, sans le réécrire pour System.ICloneable.Clone(). Et j'ai seulement besoin d'implémenter l'interface ICloneable . Sans écrire des méthodes qui sont cachées par cette méthode. –

+1

Dans ce cas, je supprimer toute référence à l'interface non générique, et sans la contrainte, tout devrait bien se passer. –

Questions connexes