C# 使用';这';作为一般参数,转换问题
这可能吗?当我编译时,我得到一个错误,说即使有约束也不能将组件转换为TComponentC# 使用';这';作为一般参数,转换问题,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
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。一个具体的例子可能有助于理解这一点。。。我现在明白问题了,那很棘手。谢谢你的解释。