abstract class A<T> where T:A<T>
{
public event Action<T> Event1;
}
class B : A<B>
{
//has a field called Action<B> Event1;
}
有沒有更好的方法來做到這一點?我想要基類中的東西(事件等)能夠使用子類的類型。最好的方法來引用我自己的類型
abstract class A<T> where T:A<T>
{
public event Action<T> Event1;
}
class B : A<B>
{
//has a field called Action<B> Event1;
}
有沒有更好的方法來做到這一點?我想要基類中的東西(事件等)能夠使用子類的類型。最好的方法來引用我自己的類型
您使用的模式實際上並未實現您想要的約束。假設你想「模型的動物只能是與它自己的一種友好的東西」:
abstract class Animal<T> where T : Animal<T>
{
public abstract void GetFriendly(T t);
}
class Cat : Animal<Cat>
{
public override void GetFriendly(Cat cat) {}
}
我們是否已經成功實施所需的約束?
class EvilDog : Animal<Cat>
{
public override void GetFriendly(Cat cat) {}
}
現在一隻邪惡的狗可以與任何貓友好,而不會與其他邪惡的狗友好。
您想要的類型約束在C#類型系統中是不可能的。如果您需要類型系統強制執行的這種約束,請嘗試使用Haskell。
看我對這個問題的文章瞭解詳情:
http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx
我認爲你指出了一個重要的限制,但依賴於根據實際要求,這可能會或可能不是一個嚴重的問題。例如,如果僅在自己的代碼庫中使用它,如果模式正確實現,則風格上可能很明顯。 – kvb 2011-06-10 23:31:04
有趣的事情就是這個。我完全不同意。對於您認爲這種技術存在的問題有一個簡單的解決方案。 http://blog.theobjectguy.com/2011/06/curiously-recurring-template-pattern.html – TheObjectGuy 2011-06-22 02:36:51
你的工作得很好。事實上,它非常類似於你想要的界面實現者使用你的類型其他.NET接口和類型,如:
public class MyClass : IEqualityComparer<MyClass>
{
// From the interface IEqualityComparer
public bool Equals(MyClass other) { ... }
...
}
由於A是抽象的,你可以從一個添加的抽象方法,A和調用它們, B,將被強制執行的方法,將是調用:
abstract class A<T> where T:A
{
public event Action<T> Event1;
public abstract void Method();
public A(){Method();}
}
class B : A<B>
{
//has a field called Action<B> Event1;
public void Method(){ //stuff }
}
在B的實例,基類的構造函數會調用()方法,這是隻有B中實施,迫使B的實例被稱爲。
這允許A調用子類特定的方法,而不要求A具有兒童的特定知識。缺點是所有的孩子必須實施方法或將其重新提取給自己的孩子。
要小心,一個基類不應該有直接的知識的它的子類,它變成一個討厭的一塊技術債務。在這種情況下,因爲它是一個通用的,它不是太糟糕,但只是一般。 – 2011-06-10 17:18:30
難道你不是指'在哪裏T:A'? Eric Lippert已經寫過這樣的內容:http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx –
2011-06-10 17:35:05