6
votes

Comment faire une sous-classe commune pour supprimer le code dupliqué

J'ai deux classes que l'une est dérivée de la liste de coasser et du second de Dropdownlist. Le code à l'intérieur d'eux est exactement le même. La seule différence est que j'en ai besoin en premier dans des endroits où j'ai besoin d'afficher CoaseboxList et deuxième pour montrer Dropdownlist. Vous trouverez ci-dessous mon code: xxx

la seconde one xxx

Maintenant, comme vous pouvez le voir, le code interne est exactement le même que je veux éviter. Comment puis-je faire une classe commune pour qu'il puisse supprimer du duplicacy de code?


2 commentaires

+1 pour s'efforcer de réduire la redondance dans votre code. Votre question peut être mieux adaptée ici cependant: codereview.stackexchange.com


@Kileynaro: cool de savoir savoir sur Codereview, ne savait pas qu'il existait. Ne pense pas que c'est un mauvais match pour le cas non plus. Bonne question que je pense. +1


4 Réponses :


3
votes

Vous pouvez créer une troisième classe xxx

, puis l'utiliser dans d'autres classes xxx


3 commentaires

Mais cela mène à chercher mes propriétés comme une entité.a et une entité.b. Je veux éviter ça. Je veux les propriétés directement à partir de mes pages ASPX.


@Rocky: encapsuler l'entité, le rendre privé et créer une propriété sur votre classe pour y accéder.


+1 pour l'utilisation de la composition, la seule chose à gauche faisait une entité interne, en utilisant l'encapsulation si externe, elle n'est pas nécessaire



0
votes

Vous ne pouvez pas, car c # ne prend pas en charge de multiples héritage de la mise en œuvre (et que vous êtes déjà sous-classement). Vous pouvez refacturer une partie du code dans une troisième classe et que chacune de vos classes ait une instance et déléguer des appels.

Vous pouvez essayer quelque chose comme ceci: http://www.codeproject.com/kb /architecture/smip.aspx , mais cela ressemble à beaucoup de travail.


6 commentaires

Juste parce que je suis curieux et je n'ai vraiment aucune idée, cela vous dérangerait-il d'élaborer comment on pourrait utiliser des délégués pour atteindre ce que la PO recherche?


Je voulais juste déléguer les appels au troisième objet. Je ne faisais pas référence au délégué C #.


Merci pour la clarification. Je comprends ce que tu veux dire!


@Kiley: Cet article est absurde, il existe des modèles de conception courants pour gérer cela, il n'ya pas eu de "héritage multiple simulé". Ni le code que l'article ne fonctionne ni le nom est valide. Il existe des modèles de conception testés et éprouvés à utiliser à la place.


@Arjang hmm, intéressant ... Je n'ai même pas regardé l'article de codeProject! Juste pour être approfondi, pouvez-vous suggérer une lecture sur les modèles de conception testés et éprouvés que vous recommanderiez à la place de MI pour C #?


@Kiley: la composition est la manière dont ils gèrent les avantages que Mi apporte, il n'est pas nécessaire d'avoir un MI si on peut avoir ses avantages. "Des motifs de conception en C #" est un bon point de départ. Consultez également Dofacory.com/patterns/patterns.aspx .



0
votes

Vous utilisez la composition, créez une autre classe qui n'est pas liée à ces deux classes, puis disposez du code commun de celui-ci, lorsque vous devez utiliser le code dans les deux classes, vous faites une instance, vous pouvez également l'utiliser Thorugh un interface. Pas besoin d'utiliser inheritNece.

mise à jour: CODE ci-dessous (modifié le code déjà fourni par MEZIANOU) P>

 internal interface IEntity
    {
        int A { get; set; }
        int B { get; set; }
        Collection<int> GetCollection { get; }
    }

    internal class Entity : TrialBalanceHTMLToDataTable.TrialBalance.IEntity
    {
        public int A { get; set; }
        public int B { get; set; }
        public Collection<int> GetCollection
        {
            get{
            //dummy task 
            Collection<int> ints = new Collection<int>();
            //........ 
            return ints;
            }
        }
    }


    public class MyDropDownList : DropDownList
    {
        public MyDropDownList() { _Entity = new Entity(); }

        private IEntity _Entity { get; set; }
        protected override void OnLoad(EventArgs e)
        {
            this.DataSource = _Entity.GetCollection;
            this.DataBind();
        }
    }


5 commentaires

-1 pour dire qu'une interface résoudra le problème; Les définitions seront toujours dupliquées entre les deux classes implémentant l'interface. Mais vous obtenez +1 pour suggérer que le code commun soit déplacé vers une autre classe ... alors vous cassez même!


@Kileynaro: lol :), les interfaces ne résolvent pas de problèmes, ils vous permettent de les laisser les uniformiser!


@Kileynaro: Non! La classe commune implémente l'interface que les deux autres catégories ne l'utiliseront que pour parler à la classe qui l'applique, l'idée n'était pas d'implément des interfaces dans deux cours différentes.


Je pense que je suis un peu confus ... Pourriez-vous fournir un petit extrait de code pour aider à clarifier?


@Kileynaro: Mise à jour de la modification du code déjà fourni par MEZIANTOU.



0
votes

Il semblerait que ce que vous essayez d'accomplir est d'avoir une seule classe, c'est code> mydropdownlist code>, être capable d'hériter des propriétés à partir de la Dropdownlist code>, et d'avoir Les propriétés MyCheckBox CODE> Classe de la catégorie Code> Cochez la case CODE> CLASSE, tandis que lorsque vous avez vos deux classes mes * ont des propriétés supplémentaires, ce qui est identique.

Comme d'autres ont suggéré, Le moyen le plus simple d'accomplir cela serait via héritage multiple . Dans votre exemple spécifiquement, cela signifierait la création d'un (éventuellement abstrait ) qui décrit les attributs partagés entre MyDropDownList code> et MyCheckBox CODE>, puis les deux classes hériter de leurs bases respectives System.Web.ui.webControls ainsi que ce "partagé" classer. Cependant, comme il a été dit, c # ne prend pas en charge plusieurs héritage. de Chris Brumme via ce lien: P>

Le nombre d'endroits où Mi est vraiment approprié est en fait assez petit. Dans de nombreux cas, plusieurs interfaces héritage peuvent faire le travail effectué à la place. Dans d'autres cas, vous pourrez peut-être utiliser l'encapsulation et la délégation. P> blockQuote>

Vous avez peut-être également envisagé d'utiliser interfaces . Ce, comme vous l'avez peut-être découvert, constituerait un choix inapproprié pour votre solution comme une interface vous permet uniquement de définir qu'il existe certaines propriétés et méthodes d'une classe, mais pas à quel point les propriétés ou les méthodes sont définies. Strong> Encore une fois, c'est un choix inapproprié pour éliminer le code dupliqué. P>

Qu'est-ce que cela signifie pour vous? Eh bien, si vous souhaitez écrire un MyDropDowlist CODE> Classe prenant en charge les deux myCustomdDlinStance.selectedindex code> et myCustomddlinStance.a code> syntaxes, vous devrez faire Un peu de "magie". Mais le fait que votre langue ne supporte pas ce que vous essayez de faire devrait soulever un drapeau rouge! STRUT> Ce n'est pas nécessairement faux, mais cela devrait être un indicateur fort que vous voudrez peut-être réexaminer votre conception. P>

Je suppose que la partie dupliquée des deux classes peut rester seule à sa propre entité logique. Cela signifie que vous pouvez créer à juste titre votre propre classe pour contenir ces propriétés et méthodes partagées. Voici ce que nous obtenons: p>

samplecontrol.cs strong> p> xxx pré>

si csharp prenait en compte plusieurs héritage, votre MyDropDownList Code> La classe pourrait hériter des deux DropDownlist code> et samplecontrol code> et vous auriez fait. Mais encore une fois, ce n'est pas possible. P>

Alors, comment pouvons-nous accomplir votre objectif? C'est un peu compliqué, mais vous pouvez encapsuler vos propriétés et méthodes partagées dans chacune de vos classes personnalisées. Voici un exemple pour la classe code> MyDropDownList Code> (Notez que MyCheckBoxList CODE> serait identique, modifier simplement le nom de la classe: P>

public class MyDropDownList : DropDownList
{
    private SampleControl mySampleControl { get; set; }

    public int A
    {
        get
        {
            return mySampleControl.A;
        }

        set
        {
            mySampleControl.A = value;
        }
    }

    public int B
    {
        get
        {
            return mySampleControl.B;
        }

        set
        {
            mySampleControl.B = value;
        }
    }

    public MyDropDownList()
    {
        mySampleControl = new SampleControl();
    }

    protected override void OnLoad(EventArgs e)
    {
        //dummy task
        this.DataSource = mySampleControl.MysteryCollection;
        this.DataBind();
    }
}


0 commentaires