这是我会做:
保留链接作为一个抽象类,使用工厂实例并通过在关闭/匿名方法作为工厂的构建方法的参数。通过这种方式,您可以使用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类中声明尽可能多的动作的可选实现。
下面是相关的链接类(使用密封的生成器内部类)。
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.Builder.Build("id",
OnClick:() =>
{
// SetResponsePage(...);
Console.WriteLine("Click!");
},
OnFoo:() =>
{
Console.WriteLine("Foo!");
Console.ReadLine();
}
);
为什么这很酷?让我们来看看新的链接类:
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;
}
}
里面的静态类生成器,还有一个工厂方法构建需要在1个所需的参数(ID)和3个可选参数,的OnClick,OnFoo和OnBar会。如果他们没有分配,工厂方法给他们一个默认的实现。
因此,在您的Link的构造函数的参数参数中,只需要实现所需的方法,否则它们将使用默认操作,该操作可能不是任何操作。
但是,缺点是在最后一个例子中,Link类不是抽象的。但它不能在Link类的范围之外实例化,因为它的构造函数是私有的(强制使用Builder类来实例化链接)。
您也可以直接将可选参数移动到Link的构造函数中,从而避免完全需要工厂。
我在你给的例子中看不到一个匿名的内部类。如果你希望你的抽象类的实现者总是实现一些方法,你可以在类中创建一个抽象方法或者让它实现一个接口。 – tenor 2011-01-22 20:05:55
@tenor,定义了一个内联的匿名类,它从`Link`继承并覆盖`onClick`方法。与Java不同,C#不支持匿名类从给定的用户类型派生。 – 2011-01-22 20:13:18
@Darin Dimitrov,谢谢你的指出。我正在寻找一个真正的“内部/嵌套”类。所提供的示例看起来更像是一个匿名类,它从现有类派生,至少使用C#术语。 – tenor 2011-01-22 20:17:15