添加附加功能的继承替代方案
Alternatives to inheritance to adding additional functionality
问题:Windows.Forms 框架中有两个 class 已经相互继承(BindingNavigator 和 ToolStrip),因此无法插入继承。扩展两个具有相同功能的不同 class 的选项或最佳选项是什么(为了 UI 一致性)?
我在装饰器方面取得了一些成功,但这需要转换到共享接口。
我已经设法使用策略模式的变体以及 c# 8 默认接口使其正常工作。每个扩展 class 都有一个具有所有附加功能的辅助对象。我从助手 class 中提取了一个接口,向其添加了一个助手参数,扩展的 classes 实现了它。 Helper 传递给父级,而接口重新映射方法,使它们直接显示。 (添加() => Helper.Add())。这样所有功能都显示在扩展 class 上,就好像它是继承的一样,并且 classes 可以完全无关。
public class ToolStripCustomUI
{
private ToolStrip _toolStrip;
public ToolStripButton ButtonAdd { get; set; } = new();
public ToolStripButton ButtonDelete { get; set; } = new();
// more controls
public ToolStripCustomUI(ToolStrip toolStrip)
{
_toolStrip = toolStrip;
Setup();
}
public void Setup() { // do stuff }
// More methods
}
public interface ICustomToolStrip
{
public ToolStripButton ButtonAdd
{
get => CustomUI.ButtonAdd;
set => CustomUI.ButtonAdd = value;
}
public ToolStripButton ButtonDelete
{
get => CustomUI.ButtonDelete;
set => CustomUI.ButtonDelete = value;
}
// more controls
ToolStripCustomUI CustomUI { get; }
public void Setup() => CustomUI.Setup();
// Other methods
}
public class ToolStripDecorator : ToolStrip, ICustomToolStrip
{
public ToolStripCustomUI CustomUI
=> new ToolStripCustomUI(this);
public ToolStripDecorator()
=> CustomUI.Setup();
}
public class CustomBindingNavigator : BindingNavigator, ICustomToolStrip
{
public ToolStripCustomUI CustomUI => new
ToolStripCustomUI(this);
public CustomBindingNavigator() : base(true)
{
Items.Remove(AddNewItem);
Items.Remove(DeleteItem);
CustomUI.Setup();
}
}
有没有更好更正确的做法?
这是一种使用针对您的自定义界面的扩展方法的方法。扩展方法是静态 class 上的一种特殊静态方法,允许您将新功能附加到任何 class 或接口。
有关扩展方法的更多信息here
我删除了所有实现细节以演示类型如何连接。
public class ToolStrip { }
public class BindingNavigator { }
public static class CustomToolStripExtensions
{
public static void Setup<T>( this T target ) where T: ICustomToolStrip
{
// do setup work here!
}
}
public interface ICustomToolStrip { }
public class ToolStripDecorator : ToolStrip, ICustomToolStrip
{
public ToolStripDecorator()
{
this.Setup<ToolStripDecorator>();
}
}
public class CustomBindingNavigator : BindingNavigator, ICustomToolStrip
{
public CustomBindingNavigator()
{
this.Setup<CustomBindingNavigator>();
}
}
我确定的解决方案是完全不直接扩展 ToolStrip 或 BindingNavigator。相反,我创建了一个新的 CustomToolStrip class,它有一个 ToolStrip 对象作为 属性,并将所有新功能添加到 Toolstrip 对象。然后,我创建了一个扩展 CustomToolStrip 的 CustomBindingNavigator class,并添加了所有 BindingNavigator 特定功能。 ToolStrip 属性 我覆盖了它以使其成为 BindingNavigator。
在自定义工具条中
private virtual ToolStrip ToolStrip { get; set; } = new ToolStrip();
在 CustomBindingNavigator 中
private override ToolStrip ToolStrip {get; set;} = new BindingNavigator();
然后可以注入工具条以成为装饰器模式。
问题:Windows.Forms 框架中有两个 class 已经相互继承(BindingNavigator 和 ToolStrip),因此无法插入继承。扩展两个具有相同功能的不同 class 的选项或最佳选项是什么(为了 UI 一致性)?
我在装饰器方面取得了一些成功,但这需要转换到共享接口。
我已经设法使用策略模式的变体以及 c# 8 默认接口使其正常工作。每个扩展 class 都有一个具有所有附加功能的辅助对象。我从助手 class 中提取了一个接口,向其添加了一个助手参数,扩展的 classes 实现了它。 Helper 传递给父级,而接口重新映射方法,使它们直接显示。 (添加() => Helper.Add())。这样所有功能都显示在扩展 class 上,就好像它是继承的一样,并且 classes 可以完全无关。
public class ToolStripCustomUI
{
private ToolStrip _toolStrip;
public ToolStripButton ButtonAdd { get; set; } = new();
public ToolStripButton ButtonDelete { get; set; } = new();
// more controls
public ToolStripCustomUI(ToolStrip toolStrip)
{
_toolStrip = toolStrip;
Setup();
}
public void Setup() { // do stuff }
// More methods
}
public interface ICustomToolStrip
{
public ToolStripButton ButtonAdd
{
get => CustomUI.ButtonAdd;
set => CustomUI.ButtonAdd = value;
}
public ToolStripButton ButtonDelete
{
get => CustomUI.ButtonDelete;
set => CustomUI.ButtonDelete = value;
}
// more controls
ToolStripCustomUI CustomUI { get; }
public void Setup() => CustomUI.Setup();
// Other methods
}
public class ToolStripDecorator : ToolStrip, ICustomToolStrip
{
public ToolStripCustomUI CustomUI
=> new ToolStripCustomUI(this);
public ToolStripDecorator()
=> CustomUI.Setup();
}
public class CustomBindingNavigator : BindingNavigator, ICustomToolStrip
{
public ToolStripCustomUI CustomUI => new
ToolStripCustomUI(this);
public CustomBindingNavigator() : base(true)
{
Items.Remove(AddNewItem);
Items.Remove(DeleteItem);
CustomUI.Setup();
}
}
有没有更好更正确的做法?
这是一种使用针对您的自定义界面的扩展方法的方法。扩展方法是静态 class 上的一种特殊静态方法,允许您将新功能附加到任何 class 或接口。
有关扩展方法的更多信息here
我删除了所有实现细节以演示类型如何连接。
public class ToolStrip { }
public class BindingNavigator { }
public static class CustomToolStripExtensions
{
public static void Setup<T>( this T target ) where T: ICustomToolStrip
{
// do setup work here!
}
}
public interface ICustomToolStrip { }
public class ToolStripDecorator : ToolStrip, ICustomToolStrip
{
public ToolStripDecorator()
{
this.Setup<ToolStripDecorator>();
}
}
public class CustomBindingNavigator : BindingNavigator, ICustomToolStrip
{
public CustomBindingNavigator()
{
this.Setup<CustomBindingNavigator>();
}
}
我确定的解决方案是完全不直接扩展 ToolStrip 或 BindingNavigator。相反,我创建了一个新的 CustomToolStrip class,它有一个 ToolStrip 对象作为 属性,并将所有新功能添加到 Toolstrip 对象。然后,我创建了一个扩展 CustomToolStrip 的 CustomBindingNavigator class,并添加了所有 BindingNavigator 特定功能。 ToolStrip 属性 我覆盖了它以使其成为 BindingNavigator。
在自定义工具条中
private virtual ToolStrip ToolStrip { get; set; } = new ToolStrip();
在 CustomBindingNavigator 中
private override ToolStrip ToolStrip {get; set;} = new BindingNavigator();
然后可以注入工具条以成为装饰器模式。