代码之家  ›  专栏  ›  技术社区  ›  Rohan West

将“this”用作泛型参数时,转换问题

  •  1
  • Rohan West  · 技术社区  · 16 年前

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

    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; } }
    }
    
    2 回复  |  直到 16 年前
        1
  •  8
  •   Jon Skeet    16 年前

    失败的原因是 TComponent 可能是一些 其他 执行 IComponent<TKey, TComponent> . 只是因为 Component 实现接口并不意味着其他任何东西都不能:)

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

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

    在你的情况下这是否可行,我不知道,但这肯定会避免类型问题。

    另一个选择是 this 正如斯宾德建议的。这可能在执行时失败,但实际上,除非 创建一个替代的实现,但不会。这有点烦人,在使用泛型时必须强制转换,但偶尔也会发生这种情况。

    编辑:下面是一个可能出错的例子:

    public class Other : IComponent<string, Other>
    {
        // Implement interface
    }
    

    现在,如果创建一个 Component<string, Other> 是吗?它满足了约束,没有问题…但是一个 成分 不是一个 Other

    现在你 能够 像这样更改约束:

    public class Component<TKey, TComponent> : IComponent<TKey, TComponent> 
        where TComponent : Component<TKey, TComponent>
    

    即约束 T组分 组件 而不是 IComponent . 但这仍然存在问题:

    public class FooComponent : Component<string, FooComponent> {}
    public class BarComponent : Component<string, FooComponent> {}
    

    在这里,你可能想要 BarComponent 有一个 T组分 但它有一个不同的组成部分。到目前为止,您所展示的代码可能还可以,但是这种奇怪的行为可能会阻碍其他目标的实现。值得考虑…

    哦,如果你很高兴 成分 密封,在那一点上改变了约束 够了(我想!).

        2
  •  0
  •   spender    16 年前

    演员阵容怎么样:

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