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