Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何创建一个公共子类来删除重复代码_C#_Asp.net_Oop_Design Patterns - Fatal编程技术网

C# 如何创建一个公共子类来删除重复代码

C# 如何创建一个公共子类来删除重复代码,c#,asp.net,oop,design-patterns,C#,Asp.net,Oop,Design Patterns,我有两个类,一个来自CheckBoxList,另一个来自DropDownList。它们内部的代码完全相同。唯一的区别是,我需要在我需要显示复选框列表的地方显示第一个,第二个显示dropdownlist。下面是我的代码: using System; using System.Collections.ObjectModel; using System.Web.UI.WebControls; namespace Sample { public class MyChec

我有两个类,一个来自CheckBoxList,另一个来自DropDownList。它们内部的代码完全相同。唯一的区别是,我需要在我需要显示复选框列表的地方显示第一个,第二个显示dropdownlist。下面是我的代码:

using System;
using System.Collections.ObjectModel;
using System.Web.UI.WebControls;

    namespace Sample
    {
        public class MyCheckBoxList : CheckBoxList
        {
            public int A { get; set; }
            public int B { get; set; }
            protected override void OnLoad(EventArgs e)
            {
                //dummy task
                Collection<int> ints = new Collection<int>();
                //........
                this.DataSource = ints;
                this.DataBind();
            }
        }
    }
使用系统;
使用System.Collections.ObjectModel;
使用System.Web.UI.WebControl;
名称空间示例
{
公共类MyCheckBoxList:CheckBoxList
{
公共int A{get;set;}
公共int B{get;set;}
受保护的覆盖无效加载(事件参数e)
{
//虚拟任务
集合ints=新集合();
//........
this.DataSource=ints;
这个.DataBind();
}
}
}
第二个

using System;
using System.Collections.ObjectModel;
using System.Web.UI.WebControls;

namespace Sample
{
    public class MyDropDownList : DropDownList
    {
        public int  A { get; set; }
        public int  B { get; set; }
        protected override void OnLoad(EventArgs e)
        {
            //dummy task
            Collection<int> ints = new Collection<int>();
            //........
            this.DataSource = ints;
            this.DataBind();
        }
    }
}
使用系统;
使用System.Collections.ObjectModel;
使用System.Web.UI.WebControl;
名称空间示例
{
公共类MyDropDownList:DropDownList
{
公共int A{get;set;}
公共int B{get;set;}
受保护的覆盖无效加载(事件参数e)
{
//虚拟任务
集合ints=新集合();
//........
this.DataSource=ints;
这个.DataBind();
}
}
}

现在,正如您所看到的,内部代码与我想要避免的完全相同。如何为它创建一个公共类以消除代码重复性?

您可以创建第三个类

public class Entity
{
    public int  A { get; set; }
    public int  B { get; set; }
    Collection<int> GetCollection()
    {
        //dummy task
        Collection<int> ints = new Collection<int>();
        //........
        return ints;
    }
}
您不能,因为c#不支持实现的多重继承(而且您已经在子类化了)。您可以将一些代码重构为第三个类,并让每个类都有一个实例和对它的委托调用


您可以尝试这样的方法:,但看起来工作量很大。

您使用组合,创建另一个与这两个类不相关的类,然后在其中包含公共代码,当您需要在创建实例的任何类中使用代码时,您也可以通过接口使用它。无需使用inheritnece

更新:代码如下(修改了meziantou已经提供的代码)

内部接口
{
int A{get;set;}
int B{get;set;}
集合GetCollection{get;}
}
内部类实体:TrialBalanceHTMLToDataTable.TrialBalance.Entity
{
公共int A{get;set;}
公共int B{get;set;}
公共集合GetCollection
{
得到{
//虚拟任务
集合ints=新集合();
//........ 
返回整数;
}
}
}
公共类MyDropDownList:DropDownList
{
public MyDropDownList(){u Entity=new Entity();}
私有属性_实体{get;set;}
受保护的覆盖无效加载(事件参数e)
{
this.DataSource=\u Entity.GetCollection;
这个.DataBind();
}
}

您试图实现的似乎是拥有一个类,即
MyDropDownList
,能够从
DropDownList
继承属性,并让
MyCheckBox
类从
CheckBox
类继承属性,而您的两个My*类有一些额外的属性,这些属性恰好相同

正如其他人所建议的那样,实现这一点的最简单方法是通过。具体地说,在您的示例中,这意味着创建一个(可能)类来描述
MyDropDownList
MyCheckBox
之间的共享属性,然后让这两个类从各自的System.Web.UI.WebControls基以及这个“共享”类继承。然而,正如Chris Brumme所说,通过该链接:

MI真正合适的地方实际上很少。在许多情况下,多接口继承可以完成工作。在其他情况下,您可以使用封装和委派

您可能也考虑过使用。您可能已经发现,这对于您的解决方案来说是一个不合适的选择,因为接口只允许您定义类中存在某些属性和方法,而不允许您定义属性或方法的方式。因此,对于删除重复代码来说,这是一个不合适的选择

这对你意味着什么?好吧,如果你想写一个
MyDropDownList
类,它同时支持
myCustomDDLInstance.SelectedIndex
myCustomDDLInstance.a
语法,你需要做一点“魔术”但是,您的语言不支持您正在尝试的操作这一事实应该引起注意这不一定是错的,但它应该是一个强有力的指标,表明您可能希望重新检查您的设计

我的猜测是,这两个类的复制部分可以作为自己的逻辑实体独立存在。这意味着您可以合理地创建自己的类来保存这些共享属性和方法。以下是我们得到的:

SampleControl.cs

public class SampleControl
{
    public int A { get; set; }
    public int B { get; set; }

    public Collection<int> MysteryCollection
    {
        get
        {
            Collection<int> ints = new Collection<int>();
            //........
            return ints;
        }
    }
}
以这种方式设计的类虽然有点复杂,但应该能够完成您所寻找的类型语法

作为最后的说明,我强烈鼓励你至少考虑重新检查你的设计,看看是否有更好的方法来接近你的类层次结构。我的建议是,如果共享属性可以作为逻辑实体独立存在,那么它们可能应该是自己的类。如果是这样,那么该类可能是您的
MyDropDownList
MyCheckBox
类中合法且合乎逻辑的成员。这意味着您应该使用
myDropDownListInstance.SharedAttributesClassName.A
语法。是的
 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();
        }
    }
public class SampleControl
{
    public int A { get; set; }
    public int B { get; set; }

    public Collection<int> MysteryCollection
    {
        get
        {
            Collection<int> ints = new Collection<int>();
            //........
            return ints;
        }
    }
}
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();
    }
}