扩展已经继承另一个 class 的 class
extending a class that already inherits another class
我继承了一些System.Windows.Forms-Control
(大约10件)。
他们每个人都有一些自定义扩展,但每个控件的大部分扩展都是相同的。
实际上我必须为它们中的每一个单独编写相同的功能。
这是很多复制粘贴,难以维护。
class MyButton : Button
{
//this is only in MyButton
public int ButtonProperty { get; set; }
public object Property1 { get; set; }
public object Property2 { get; set; }
public void MakeInvisible()
{
this.Visible = false;
}
}
class MyLabel : Label
{
//this is only in MyLabel
public bool LabelProperty { get; set; }
//same propertys and methods as in MyButton
public object Property1 { get; set; }//copy+paste
public object Property2 { get; set; }//copy+paste
public void MakeInvisible()//copy+paste
{
this.Visible = false;
}
}
我正在寻找的是一种扩展所有派生的 classes 的方法,就像您可以使用 interface
或扩展方法一样。 但我也想拥有属性并访问基础class (Control
)
这就是我梦寐以求的:
class MyButton : Button, MyExtension
{
//this is only in MyButton
public int ButtonProperty { get; set; }
}
class MyLabel : Label, MyExtension
{
//this is only in MyLabel
public bool LabelProperty { get; set; }
}
//Extension for all classes inherited from Control
class MyExtension : Control
{
public object Property1 { get; set; }
public object Property2 { get; set; }
public void MakeInvisible()
{
this.Visible = false;
}
}
C# 不支持多重继承。 您应该尝试这样的方法 - MyButton : MyExtension;
和 MyExtension : Button
。在这种情况下,您将使用 MyExtension 和 Button classes.
扩展 MyButton class
您可以为此目的使用扩展方法
public static class ControlHelper
{
public static void MakeInvisible(this Control c)
{
c.Visible = false;
}
}
并像这样使用它
var mb = new MyButton();
mb.MakeInvisible();
var ml = new MyLabel();
ml.MakeInvisible();
通过使用这种方法,您可以为基础 类 生成扩展方法并在派生 类.
中使用它
您可以使用合成,而不是从 Button
和 Label
继承。
class MyExtension
{
protected Control control;
public MyExtension(Control control)
{
this.control = control;
}
public object Property1 { get; set; }
public object Property2 { get; set; }
public void MakeInvisible()
{
this.control.Visible = false;
}
}
class MyButton : MyExtension
{
public MyButton(Button button):base(button){}
public int ButtonProperty { get; set; }
}
class MyLabel : Label
{
public MyButton(Label label):base(label){}
public bool LabelProperty { get; set; }
}
如果您不想创建它的任何实例,您甚至可以创建 MyExtension
abstract
。这里的主要区别是您必须创建一个 Button
或 Label
才能传入,并且您可能希望将它们公开为 MyButton
和 MyLabel
的属性,所以你可以得到他们的财产。
想法:
为常用属性创建新类型
给每个控件一个属性那个类型
实施:
// TypeConverter required for PropertyGrid in design mode
// found here:
[TypeConverter(typeof(ExpandableObjectConverter))]
public class MyExtension
{
// need reference to control to work with in methods
private Control _c;
public MyExtension(Control c)
{
_c = c;
}
// can be inhereted for different controls, if necessary
public string Property1 { get; set; }
public string Property2 { get; set; }
public void MakeInvisible()
{
_c.Visible = false;
}
}
// common interface of extended controls
public interface IExtended
{
MyExtension Extra { get; }
}
// MyButton implements extended interface
public class MyButton : Button, IExtended
{
public MyButton()
{
// create extended properties for button
Extra = new MyExtension(this);
}
// for designer serialization support
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public MyExtension Extra { get; private set; }
//this is only in MyButton
public int ButtonProperty { get; set; }
}
// common extension methods
public static class MyControlHelper
{
public static void MakeInvisible<TControl>(this TControl control) where TControl : Control, IExtended
{
control.Extra.MakeInvisible();
}
public static void Rename<TControl>(this TControl control) where TControl : Control, IExtended
{
control.Text = control.Extra.Property1;
}
}
如果您需要利用扩展控件的 protected
方法和属性,那么您就走运了,如果不进行大量复制和粘贴,就无法实现您想要的效果。
如果您只需要访问 public 方法和属性,那么以下几行如何:
public interface IControlExtension
{
Foo MyProperty { get; set; }
Blah MyMethod();
}
public abstract class ControlExtension: IControlExtension
{
private Control owner;
private ControlExtension(Control owner)
{
Debug.Assert(owner != null);
this.owner = owner;
}
public static IControlExtension GetControlExtension(Control c)
{
if (c is Button ||
c is Label)
{
return new SimpleControlExtension(c);
}
if (c is Panel || ...
{
return new ContainerControlExtension(c);
}
}
public abstract Foo MyProperty { get; set; }
public abstract Blah MyMethod();
private class SimpleControlExtension: ControlExtension
{
public override Foo MyProperty { .... }
public override Blah MyMethod { ....
}
private class ContainerControlExtension: ControlExtension
{
public override Foo MyProperty { .... }
public override Blah MyMethod { .... }
}
}
现在,在您所有的扩展控件中,复制和粘贴代码最少:
public class MyButton : Button
{
public MyButton()
{
....
var controlExtension = ControlExtension.GetControlExtension(this);
}
public IControlExtension { get { return controlExtension; } }
}
我继承了一些System.Windows.Forms-Control
(大约10件)。
他们每个人都有一些自定义扩展,但每个控件的大部分扩展都是相同的。
实际上我必须为它们中的每一个单独编写相同的功能。 这是很多复制粘贴,难以维护。
class MyButton : Button
{
//this is only in MyButton
public int ButtonProperty { get; set; }
public object Property1 { get; set; }
public object Property2 { get; set; }
public void MakeInvisible()
{
this.Visible = false;
}
}
class MyLabel : Label
{
//this is only in MyLabel
public bool LabelProperty { get; set; }
//same propertys and methods as in MyButton
public object Property1 { get; set; }//copy+paste
public object Property2 { get; set; }//copy+paste
public void MakeInvisible()//copy+paste
{
this.Visible = false;
}
}
我正在寻找的是一种扩展所有派生的 classes 的方法,就像您可以使用 interface
或扩展方法一样。 但我也想拥有属性并访问基础class (Control
)
这就是我梦寐以求的:
class MyButton : Button, MyExtension
{
//this is only in MyButton
public int ButtonProperty { get; set; }
}
class MyLabel : Label, MyExtension
{
//this is only in MyLabel
public bool LabelProperty { get; set; }
}
//Extension for all classes inherited from Control
class MyExtension : Control
{
public object Property1 { get; set; }
public object Property2 { get; set; }
public void MakeInvisible()
{
this.Visible = false;
}
}
C# 不支持多重继承。 您应该尝试这样的方法 - MyButton : MyExtension;
和 MyExtension : Button
。在这种情况下,您将使用 MyExtension 和 Button classes.
您可以为此目的使用扩展方法
public static class ControlHelper
{
public static void MakeInvisible(this Control c)
{
c.Visible = false;
}
}
并像这样使用它
var mb = new MyButton();
mb.MakeInvisible();
var ml = new MyLabel();
ml.MakeInvisible();
通过使用这种方法,您可以为基础 类 生成扩展方法并在派生 类.
中使用它您可以使用合成,而不是从 Button
和 Label
继承。
class MyExtension
{
protected Control control;
public MyExtension(Control control)
{
this.control = control;
}
public object Property1 { get; set; }
public object Property2 { get; set; }
public void MakeInvisible()
{
this.control.Visible = false;
}
}
class MyButton : MyExtension
{
public MyButton(Button button):base(button){}
public int ButtonProperty { get; set; }
}
class MyLabel : Label
{
public MyButton(Label label):base(label){}
public bool LabelProperty { get; set; }
}
如果您不想创建它的任何实例,您甚至可以创建 MyExtension
abstract
。这里的主要区别是您必须创建一个 Button
或 Label
才能传入,并且您可能希望将它们公开为 MyButton
和 MyLabel
的属性,所以你可以得到他们的财产。
想法:
为常用属性创建新类型
给每个控件一个属性那个类型
实施:
// TypeConverter required for PropertyGrid in design mode
// found here:
[TypeConverter(typeof(ExpandableObjectConverter))]
public class MyExtension
{
// need reference to control to work with in methods
private Control _c;
public MyExtension(Control c)
{
_c = c;
}
// can be inhereted for different controls, if necessary
public string Property1 { get; set; }
public string Property2 { get; set; }
public void MakeInvisible()
{
_c.Visible = false;
}
}
// common interface of extended controls
public interface IExtended
{
MyExtension Extra { get; }
}
// MyButton implements extended interface
public class MyButton : Button, IExtended
{
public MyButton()
{
// create extended properties for button
Extra = new MyExtension(this);
}
// for designer serialization support
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public MyExtension Extra { get; private set; }
//this is only in MyButton
public int ButtonProperty { get; set; }
}
// common extension methods
public static class MyControlHelper
{
public static void MakeInvisible<TControl>(this TControl control) where TControl : Control, IExtended
{
control.Extra.MakeInvisible();
}
public static void Rename<TControl>(this TControl control) where TControl : Control, IExtended
{
control.Text = control.Extra.Property1;
}
}
如果您需要利用扩展控件的 protected
方法和属性,那么您就走运了,如果不进行大量复制和粘贴,就无法实现您想要的效果。
如果您只需要访问 public 方法和属性,那么以下几行如何:
public interface IControlExtension
{
Foo MyProperty { get; set; }
Blah MyMethod();
}
public abstract class ControlExtension: IControlExtension
{
private Control owner;
private ControlExtension(Control owner)
{
Debug.Assert(owner != null);
this.owner = owner;
}
public static IControlExtension GetControlExtension(Control c)
{
if (c is Button ||
c is Label)
{
return new SimpleControlExtension(c);
}
if (c is Panel || ...
{
return new ContainerControlExtension(c);
}
}
public abstract Foo MyProperty { get; set; }
public abstract Blah MyMethod();
private class SimpleControlExtension: ControlExtension
{
public override Foo MyProperty { .... }
public override Blah MyMethod { ....
}
private class ContainerControlExtension: ControlExtension
{
public override Foo MyProperty { .... }
public override Blah MyMethod { .... }
}
}
现在,在您所有的扩展控件中,复制和粘贴代码最少:
public class MyButton : Button
{
public MyButton()
{
....
var controlExtension = ControlExtension.GetControlExtension(this);
}
public IControlExtension { get { return controlExtension; } }
}