3 votes

Génériques, classes abstraites, constructeurs

J'ai une classe de base abstraite

class AbstractClass 
{
    Col<AbstractClass> parent

    public AbstractClass()
    {
        //do stuff
    }
}

J'ai deux implémentations

class A : AbstractClass 
{ 
    Col<A> parent

    public A(Col<A> parent)
        :base(parent)
    {
        this.parent = parent;
    }  

}

class B : AbstractClass 
{ 
    Col<B> parent

    public B(Col<B> parent)
        :base(parent)
    {
        this.parent = parent;
    }
}

J'ai une collection

class Col<T> : IList<T> where T : AbstractClass

qui doit être utilisé dans une autre classe en tant que Col<A> and Col<B> appelons cette classe C .

class C
{
    List<A> a = new List<A>()
    List<B> b = new List<B>()
}

Tout cela fonctionnerait, sauf que je veux que les types A y B de connaître la collection de leurs parents. J'ai pensé que le fait d'avoir les constructeurs suivants dans AbstractClass A, B serait acceptable, mais il semble que les contraintes génériques ne soient disponibles que pour les classes et non pour les méthodes. En gros, je voudrais les constructeurs suivants :

public AbstractClass(Col<T> where T : AbstractClass)
public A(Col<A>)
public B(Col<B>)

Les instances de A et B doivent savoir dans quelle collection elles se trouvent, mais je ne peux pas appeler le constructeur de base à partir des classes dérivées parce qu'elles sont de types différents.

Aidez-nous !

4voto

Alexey Romanov Points 39124

J'utilise souvent un modèle lié à la norme C++. modèle curieusement récurrent quand je veux faire quelque chose comme ça :

abstract class AbstractClass<TDerivedClass>
    where TDerivedClass : AbstractClass<TDerivedClass>
{
    Col<TDerivedClass> parent;

    public AbstractClass(Col<TDerivedClass> parent)
    {
        // do stuff
        this.parent = parent;
    }
}

class A : AbstractClass<A>
{ 
    public A(Col<A> parent)
        :base(parent) {}
}

class B : AbstractClass<B>
{ 
    public A(Col<B> parent)
        :base(parent) {}
}

1voto

Thomas Levesque Points 141081

Je veux que les types A et B connaissent leur collection mère.

Vous pourriez être intéressé par cet article . Je l'ai écrit en pensant à la sérialisation XML, mais il peut être utilisé dans un contexte plus général

1voto

Noldorin Points 67794

Utiliser un Collection<T> au lieu d'un type List<T> . Ils offrent fondamentalement la même fonctionnalité ( Collection<T> utilise List<T> en interne), et est destiné précisément à cet effet.

Vous pouvez alors remplacer InsertItem pour définir le parent de tout élément ajouté à la collection.

public class MyCollection<T> : System.Collections.ObjectModel.Collection<T>
{
    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);
        item.Parent = this;
    }
}

0voto

Matt Jacobsen Points 2151

D'après ce que j'ai compris, cela n'est pas possible en C#. 2.0 . La fonctionnalité est déjà présente dans le CLR, mais C# ne la permet pas. En C# 2.0, nous avons des génériques invariants. En C# 4.0, la variance sera prise en charge.

Voici mes références :

http://blogs.msdn.com/rmbyers/archive/2005/02/16/375079.aspx

http://code.msdn.microsoft.com/csharpfuture

http://channel9.msdn.com/pdc2008/TL16/

Ai-je raison ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X