C# 如何创建一个公共子类来删除重复代码
我有两个类,一个来自CheckBoxList,另一个来自DropDownList。它们内部的代码完全相同。唯一的区别是,我需要在我需要显示复选框列表的地方显示第一个,第二个显示dropdownlist。下面是我的代码: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
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();
}
}