这就是我要做的:
将链接保留为抽象类,使用工厂对其进行实例化,并将您的闭包/匿名方法作为工厂构建方法的参数传递。这样,您可以将 Link 作为抽象类保留您的原始设计,强制通过工厂实现,并且仍然在工厂内隐藏 Link 的任何具体痕迹。
这是一些示例代码:
class Program
{
static void Main(string[] args)
{
Link link = LinkFactory.GetLink("id", () =>
// This would be your onClick method.
{
// SetResponsePage(...);
Console.WriteLine("Clicked");
Console.ReadLine();
});
link.FireOnClick();
}
public static class LinkFactory
{
private class DerivedLink : Link
{
internal DerivedLink(String id, Action action)
{
this.ID = id;
this.OnClick = action;
}
}
public static Link GetLink(String id, Action onClick)
{
return new DerivedLink(id, onClick);
}
}
public abstract class Link
{
public void FireOnClick()
{
OnClick();
}
public String ID
{
get;
set;
}
public Action OnClick
{
get;
set;
}
}
}
编辑:实际上,这可能更接近你想要的:
Link link = new Link.Builder
{
OnClick = () =>
{
// SetResponsePage(...);
},
OnFoo = () =>
{
// Foo!
}
}.Build("id");
它的美妙之处在于它使用了一个 init 块,允许您在 Link 类中声明任意数量的可选操作实现。
这是相关的 Link 类(带有密封的 Builder 内部类)。
public class Link
{
public sealed class Builder
{
public Action OnClick;
public Action OnFoo;
public Link Build(String ID)
{
Link link = new Link(ID);
link.OnClick = this.OnClick;
link.OnFoo = this.OnFoo;
return link;
}
}
public Action OnClick;
public Action OnFoo;
public String ID
{
get;
set;
}
private Link(String ID)
{
this.ID = ID;
}
}
这与您正在寻找的内容很接近,但我认为我们可以使用可选的命名参数(C# 4.0 功能)更进一步。让我们看一下带有可选命名参数的 Link 的示例声明:
Link link = Link.Builder.Build("id",
OnClick: () =>
{
// SetResponsePage(...);
Console.WriteLine("Click!");
},
OnFoo: () =>
{
Console.WriteLine("Foo!");
Console.ReadLine();
}
);
为什么这很酷?让我们看一下新的 Link 类:
public class Link
{
public static class Builder
{
private static Action DefaultAction = () => Console.WriteLine("Action not set.");
public static Link Build(String ID, Action OnClick = null, Action OnFoo = null, Action OnBar = null)
{
return new Link(ID, OnClick == null ? DefaultAction : OnClick, OnFoo == null ? DefaultAction : OnFoo, OnBar == null ? DefaultAction : OnBar);
}
}
public Action OnClick;
public Action OnFoo;
public Action OnBar;
public String ID
{
get;
set;
}
private Link(String ID, Action Click, Action Foo, Action Bar)
{
this.ID = ID;
this.OnClick = Click;
this.OnFoo = Foo;
this.OnBar = Bar;
}
}
在静态类 Builder 内部,有一个工厂方法 Build,它接受 1 个必需参数(ID)和 3 个可选参数,OnClick、OnFoo 和 OnBar。如果它们没有被分配,工厂方法会给它们一个默认的实现。
所以在你的构造函数的参数参数中,你只需要实现你需要的方法,否则它们将使用默认操作,这可能什么都没有。
然而,缺点是在最后一个示例中,Link 类不是抽象的。但是它不能在Link类的范围之外实例化,因为它的构造函数是私有的(强制使用Builder类来实例化Link)。
您还可以将可选参数直接移动到 Link 的构造函数中,从而完全不需要工厂。