【问题标题】:The type must be convertible in order to use it as parameter in the generic class类型必须是可转换的,才能在泛型类中用作参数
【发布时间】:2016-06-20 15:29:02
【问题描述】:

鉴于当前泛型类的结构。

public abstract class Foo<TFoo, TBar>
    where TFoo : Foo<TFoo, TBar>
    where TBar : Bar<TFoo, TBar>
{
}

public abstract class Foo<TFoo> : Foo<TFoo, BarImpl>
    where TFoo : Foo<TFoo>
{
}

public class FooImpl : Foo<FooImpl>
{
}

public abstract class Bar<TFoo, TBar>
    where TFoo : Foo<TFoo, TBar>
    where TBar : Bar<TFoo, TBar>
{
}

public abstract class Bar<TFoo> : Bar<TFoo, BarImpl>
    where TFoo : Foo<TFoo>
{
}

public class BarImpl : Bar<FooImpl>
{
}

我想要的是在Foo&lt;TFoo&gt; 的每个实现上设置一个默认的Bar。 在代码的其他部分,创建了一个 TBar 的实例,如果它是 Bar&lt;TFoo&gt; 则失败,因为这是一个 abstract 类。

但是,抛出了以下错误,我不明白我能做什么,或者这是否可能。

类型“BarImpl”必须可转换为“Bar”才能在泛型类“Foo”中用作参数“TBar”

我已经尝试让BarImpl 派生自Bar&lt;FooImpl, BarImpl&gt;,但没有任何效果。

改成

public abstract class Foo<TFoo> : Foo<TFoo, Bar<TFoo>>
    where TFoo : Foo<TFoo>
{
}

public abstract class Bar<TFoo> : Bar<TFoo, Bar<TFoo>>
    where TFoo : Foo<TFoo>
{
}

Bar&lt;TFoo&gt; 类型的对象被实例化(因为它是抽象的)之前一直有效。

【问题讨论】:

  • 泛型和间接的级别可能太多了。我使我头晕目眩,试图遵循哪种类型继承或实现或基于或遵循约束。你有没有机会简化这个例子?
  • 是不是 Foo 不能创建它自己的 Bar 实例,而是提供(构造函数)或从 FooImpl 继承?
  • @LasseV.Karlsen 我很高兴能简化这个过程,因为这几天我的脑袋都在旋转。任何想法将不胜感激。不确定我的问题是否清楚地表明了我在这里想要实现的目标......
  • 这是我还是你有一个无限循环? abstract class Foo&lt;TFoo, TBar&gt; where TFoo : Foo&lt;TFoo, TBar&gt;,然后是 Foo&lt;TFoo, TBar&gt; is equal to Foo&lt;Foo&lt;Foo&lt;..., TBar&gt;, TBar&gt;, TBar&gt;。你甚至如何实例化它?
  • @romain-aga,这正是我的想法。鸡下蛋但等待......

标签: c# oop generics inheritance


【解决方案1】:

我猜你必须结束你的通用递归循环:

通用接口:

public interface IFoo
{
}

public interface IBar
{
}

取决于你想要什么类型的继承:

public interface IFoo<TFoo> : IFoo
    where TFoo : IFoo
{
}

public interface IBar<TBar> : IBar
    where TBar : IBar
{
}

public interface IFoo<TFoo, TBar> : IFoo<IFoo>
    where TFoo : IFoo
    where TBar : IBar
{
}

public interface IBar<TFoo, TBar> : IBar<IBar>
    where TFoo : IFoo
    where TBar : IBar
{
}

或者:

public interface IFoo<TFoo, TBar> : IFoo
    where TFoo : IFoo
    where TBar : IBar
{
}

public interface IBar<TFoo, TBar> : IBar
    where TFoo : IFoo
    where TBar : IBar
{
}

public interface IFoo<TFoo> : IFoo<TFoo, IBar>
    where TFoo : IFoo
{
}

public interface IBar<TBar> : IBar<IFoo, TBar>
    where TBar : IBar
{
}

抽象类:

public abstract class AFoo<TFoo, TBar> : IFoo<TFoo, TBar>
    where TFoo : IFoo
    where TBar : IBar
{
}

public abstract class ABar<TFoo, TBar> : IBar<TFoo, TBar>
    where TFoo : IFoo
    where TBar : IBar
{
}

实现类:

public class Foo<TFoo, TBar> : AFoo<TFoo, TBar>
    where TFoo : IFoo
    where TBar : IBar
{
}

public class Bar<TFoo, TBar> : ABar<TFoo, TBar>
    where TFoo : IFoo
    where TBar : IBar
{
}


public class Foo<TFoo> : AFoo<TFoo, IBar>
    where TFoo : IFoo
{
}

public class Bar<TBar> : ABar<IFoo, TBar>
    where TBar : IBar
{
}

public class Foo : AFoo<IFoo, IBar>
{
}

public class Bar : ABar<IFoo, IBar>
{
}

用法:

var test = new Foo<IFoo<IFoo<IFoo, IBar<IFoo, IBar>>, IBar>, IBar>();

我仍然不明白你在这里要完成什么,有更好的解释应该有更好的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多