与自引用类型约束的泛型类 [英] Generic class with self-referencing type constraint

查看:168
本文介绍了与自引用类型约束的泛型类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑下面的代码:

 抽象类Foo< T> 
,其中T:富< T> ;,新的()
{
无效测试()
{
如果(!酒吧= NULL)
栏(这个);
}

公共事件酒吧和LT; T>酒吧;
}

委托无效酒吧< T>(T富)
,其中T:富<吨>中新();



栏(这)结果以下编译器错误:结果
参数类型的Foo< T>不分配给参数类型T



T约束为富< T>因为我想派生类大致看出基类的类型,所以该类型可以在事件回调,以便从有到回调参数转换为派生类型保存实现者使用。



我可以看到代码完全不是那么回事,但我有一点堵塞就如何正确地做到这一点,而不与可用于任何旧事物的泛型委托结束了。我也不太清楚为什么的T约束不创建一个编译器错误认为它似乎是递归的。



修改



我要澄清这一点,我想!这里有一个新的例子,我希望会更加清晰。注意下面,下面的 OnDuckSpoke 事件处理程序生成编译器错误。



我如何获得该事件传递正确的类型

 抽象类动物< T> 
,其中T:动物< T> ;,新的()
{
无效测试()
{
如果(!AnimalReady = NULL)
AnimalReady(这个);
}

公共事件AnimalHandler< T> AnimalReady;
}

委托无效AnimalHandler< T>(动物< T>动物)
,其中T:动物< T> ;,新();

级鸭:动物<鸭肉GT;
{
公共无效空翻()
{
}
}

类测试
{
无效的主要()
{
鸭=新鸭();
duck.AnimalReady + = OnDuckReady; //编译器错误
}

无效OnDuckReady(鸭)
{
duck.FlyAway();
}
}


解决方案

您可投'这个'到T:

 酒吧((T)本); 

这如果您有以下但会失败:

 公共类MyFoo:美孚< MyFoo> {} 

公共类MyOtherFoo:美孚< MyFoo> {}

由于'MyOtherFoo'不是'MyFoo'的一个实例。在这后由埃里克利珀, C#的设计师之一。


Consider the following code:

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();

The line Bar(this) results in the following compiler Error:
Argument type Foo<T> is not assignable to parameter type T

T is constrained to Foo<T> as I want derived classes to basically tell the base class their type, so that the type can be used in the event callback in order to save the implementor from having to cast the callback argument to the derived type.

I can see the code doesn't quite work but I'm having a bit of a blockage as to how to do this correctly without ending up with a generic delegate that can be used for any old thing. I'm also not quite sure why the T constraint doesn't create a compiler error considering it seems to be recursive.

EDIT

I need to clarify this I think! Here's a new example which, I hope will be much clearer. Note below that the OnDuckSpoke event handler below generates a compiler error.

How do I get the event to pass in the correct type?

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();
    }
}

解决方案

You can cast 'this' to T:

Bar((T)this);

This however will fail if you have the following:

public class MyFoo : Foo<MyFoo> { }

public class MyOtherFoo : Foo<MyFoo> { }

Because 'MyOtherFoo' is not an instance of 'MyFoo'. Take a look at this post by Eric Lippert, one of the designers of C#.

这篇关于与自引用类型约束的泛型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆