這是我會做:
保留鏈接作爲一個抽象類,使用工廠實例並通過在關閉/匿名方法作爲工廠的構建方法的參數。通過這種方式,您可以使用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