引用我自己的类型的最佳方式

abstract class A where T:A { public event Action Event1; } class B : A { //has a field called Action Event1; } 

有没有更优雅的方式来做到这一点? 我希望基类中的东西(事件等)能够使用子类的类型。

您使用的模式实际上并未实现您想要的约束。 假设您想要模仿“动物只能与自己的某种东西友好”:

 abstract class Animal where T : Animal { public abstract void GetFriendly(T t); } class Cat : Animal { public override void GetFriendly(Cat cat) {} } 

我们是否成功实现了所需的约束? 没有。

 class EvilDog : Animal { public override void GetFriendly(Cat cat) {} } 

现在,一只邪恶的狗可以与任何猫友好,并且与其他邪恶的狗不友好。

您想要的类型约束在C#类型系统中是不可能的。 如果您需要类型系统强制执行此类约束,请尝试Haskell。

有关详细信息,请参阅我关于此主题的文章:

http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx

你的工作得很好。 事实上,它与其他.NET接口和类型非常相似,您希望接口实现者使用您的类型,例如:

 public class MyClass : IEqualityComparer { // From the interface IEqualityComparer public bool Equals(MyClass other) { ... } ... } 

我认为你不需要指定T:A的位置。

当你使用B级时,T将是B:A

这也称为CRTP或奇怪的重复模板模式 ,是一种已知的习语。

由于A是抽象的,你可以向A添加抽象方法并从A和B调用它们,这将被强制实现该方法,将是调用者:

 abstract class A where T:A { public event Action Event1; public abstract void Method(); public A(){Method();} } class B : A { //has a field called Action Event1; public void Method(){ //stuff } } 

在B的实例化时,基类构造函数将调用Method(),它只在B中实现,强制调用B的实例。

这允许A调用子类特定的方法,而不需要A具有Children的特定知识。 缺点是所有孩子必须实施Method或将其重新抽象给自己的孩子。

我最近的问题被标记为此问题的副本。 我完全同意这个问题。 所以我来到这里看看答案并阅读Eric的post(非常有趣)。 您无法在编译时使用类型系统强制执行此操作,但您可以在运行时执行此操作。 我实现这个的方式是:

 abstract class FooBase { protected FooBase() { if (typeof(T) != GetType()) { throw new InvalidOperationException(); } } } 

通过这样做,我们可以种下邪恶的狗的种子,但那只狗会在运行时中止。