考虑以下代码:
abstract class Foo<T>
where T : Foo<T>, new()
{
void Test()
{
if(Bar != null)
Bar(this);
}
public event Bar<T> Bar;
}
delegate void Bar<T>(T foo)
where T : Foo<T>, new();
Bar(this)
行导致以下编译器错误:
参数类型 Foo
T 被限制为 Foo
我可以看到代码并不能很好地工作,但我对如何正确地执行此操作有一点障碍,而不会以可用于任何旧事物的通用委托(delegate)结束。考虑到它似乎是递归的,我也不太确定为什么 T 约束不会产生编译器错误。
编辑
我想我需要澄清一下!这是一个新的例子,我希望它会更清楚。请注意下面的 OnDuckReady
事件处理程序会生成编译器错误。
如何让事件以正确的类型传递?
abstract class Animal<T>
where T : Animal<T>, new()
{
void Test()
{
if(AnimalReady != null)
AnimalReady(this);
}
public event AnimalHandler<T> AnimalReady;
}
delegate void AnimalHandler<T>(Animal<T> animal)
where T : Animal<T>, new();
class Duck : Animal<Duck>
{
public void FlyAway()
{
}
}
class Test
{
void Main()
{
Duck duck = new Duck();
duck.AnimalReady += OnDuckReady; // COMPILER ERROR
}
void OnDuckReady(Duck duck)
{
duck.FlyAway();
}
}
最佳答案
你可以将 'this' 转换为 T:
Bar((T)this);
但是,如果您有以下内容,这将失败:
public class MyFoo : Foo<MyFoo> { }
public class MyOtherFoo : Foo<MyFoo> { }
因为“MyOtherFoo”不是“MyFoo”的实例。看看this由 Eric Lippert 发表,他是 C# 的设计者之一。
关于c# - 具有自引用类型约束的通用类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6618134/