C# 使用';这';作为一般参数,转换问题

C# 使用';这';作为一般参数,转换问题,c#,generics,C#,Generics,这可能吗?当我编译时,我得到一个错误,说即使有约束也不能将组件转换为TComponent public interface IComponent<TKey, TComponent> where TComponent : IComponent<TKey, TComponent> { TComponent Parent { get; } void Register(TKey key, TComponent component); void Regsit

这可能吗?当我编译时,我得到一个错误,说即使有约束也不能将组件转换为TComponent

public interface IComponent<TKey, TComponent> where TComponent : IComponent<TKey, TComponent>
{
    TComponent Parent { get; }
    void Register(TKey key, TComponent component);
    void RegsiterWith(TKey key, TComponent component);
}

public class Component<TKey, TComponent> : IComponent<TKey, TComponent> where TComponent : IComponent<TKey, TComponent>
{
    private TComponent _parent;

    public void Register(TKey key, TComponent component)
    {
        component.RegsiterWith(key, this);
    }

    public void RegsiterWith(TKey key, TComponent component)
    {
        component.Register(key, this);
    }

    public TComponent Parent { get { return _parent; } }
}
公共接口IComponent,其中TComponent:IComponent
{
t组件父级{get;}
无效寄存器(TKey密钥、TComponent组件);
void RegsiterWith(TKey、TComponent组件);
}
公共类组件:IComponent,其中TComponent:IComponent
{
私有TComponent\u父级;
公共无效寄存器(TKey、TComponent组件)
{
RegsiterWith(键,this);
}
public void RegsiterWith(TKey、TComponent组件)
{
组件。寄存器(键,this);
}
公共t组件父级{get{return}\u Parent;}
}
演员阵容如何:

public void Register(TKey key, TComponent component)
{
    component.RegsiterWith(key, (TComponent)this);
}
演员阵容如何:

public void Register(TKey key, TComponent component)
{
    component.RegsiterWith(key, (TComponent)this);
}

它失败的原因是
TComponent
实际上可能是
IComponent
的其他实现。仅仅因为
组件
实现了接口并不意味着其他任何东西都不能:)

解决此问题的一种方法是更改接口:

public interface IComponent<TKey, TComponent> 
    where TComponent : IComponent<TKey, TComponent>
{
    TComponent Parent { get; }
    void Register(TKey key, IComponent<TKey, TComponent> component);
    void RegsiterWith(TKey key, IComponent<TKey, TComponent> component);
}
现在,如果创建
组件
,会发生什么情况?它满足约束,没有任何问题。。。但是
组件
不是
其他组件

现在可以按如下方式更改约束:

public class Component<TKey, TComponent> : IComponent<TKey, TComponent> 
    where TComponent : Component<TKey, TComponent>
在这里,您可能希望
BarComponent
本身有一个
TComponent
,但它有一个不同的组件。到目前为止,您展示的代码可能还可以,但这种怪癖可能会妨碍其他目标。值得考虑的


哦,如果您很乐意将
组件
密封起来,那么此时更改的约束就足够了(我认为!)。

它失败的原因是
TComponent
实际上可能是
IComponent
的其他实现。仅仅因为
组件
实现了接口并不意味着其他任何东西都不能:)

解决此问题的一种方法是更改接口:

public interface IComponent<TKey, TComponent> 
    where TComponent : IComponent<TKey, TComponent>
{
    TComponent Parent { get; }
    void Register(TKey key, IComponent<TKey, TComponent> component);
    void RegsiterWith(TKey key, IComponent<TKey, TComponent> component);
}
现在,如果创建
组件
,会发生什么情况?它满足约束,没有任何问题。。。但是
组件
不是
其他组件

现在可以按如下方式更改约束:

public class Component<TKey, TComponent> : IComponent<TKey, TComponent> 
    where TComponent : Component<TKey, TComponent>
在这里,您可能希望
BarComponent
本身有一个
TComponent
,但它有一个不同的组件。到目前为止,您展示的代码可能还可以,但这种怪癖可能会妨碍其他目标。值得考虑的


哦,如果您很乐意将
组件
密封起来,那么此时更改的约束就足够了(我认为!)。

可能无关紧要,但是为什么在Register和RegisterWith中未使用组件参数?spender2,只需更改它,谢谢,有没有办法不使用强制转换?或者我必须等待.NET4.0?嗯。我有另一个类似的问题,看起来它必须等到4.0,然后马克·格雷威尔立刻解决了它。所以我不敢说这是一个无法解决的协变/逆变问题,因为我可能错了!如果
组件
组件
类的另一个实例,这不会导致无限循环吗?我看不出有什么可以阻止这一点。可能与此无关,但为什么在Register和RegisterWith中未使用组件param?spender2,刚刚更改了它,谢谢,有没有办法不使用强制转换?或者我必须等待.NET4.0?嗯。我有另一个类似的问题,看起来它必须等到4.0,然后马克·格雷威尔立刻解决了它。所以我不敢说这是一个无法解决的协变/逆变问题,因为我可能错了!如果
组件
组件
类的另一个实例,这不会导致无限循环吗?我看不出有什么可以阻止这一点。我不明白,为什么TComponent是否真的可以是IComponent的其他实现,只要它实现了“IComponent”,它满足约束条件,这本身对编译器来说不就足够了吗?不,因为“this”可能不是
TComponent
,但是
Register
/
Register with
的第二个参数是原始代码中的
t组件。所以它必须将“
this
”转换为
TComponent
。。。但是“
this
”可能不是一个
t组件
。当你说“可能不是”时,我不知道会是什么情况,因为“this”的类是一个IComponent。在什么情况下,这不是TComponent。一个具体的例子可能有助于理解这一点。。。我现在明白问题了,那很棘手。谢谢你解释。我不明白,为什么TComponent是否真的可以是IComponent的其他实现呢?只要它实现了“IComponent”,它满足约束条件,这本身对编译器来说不就足够了吗?不,因为“this”可能不是
TComponent
,但是
Register
/
Register with
的第二个参数是原始代码中的
t组件。所以它必须将“
this
”转换为
TComponent
。。。但是“
this
”可能不是一个
t组件
。当你说“可能不是”时,我不知道会是什么情况,因为“this”的类是一个IComponent。在什么情况下,这不是TComponent。一个具体的例子可能有助于理解这一点。。。我现在明白问题了,那很棘手。谢谢你的解释。