类型'TNestedInterface'必须可转换为'INestedInterfaceTest'才能将其用作参数'TNestedInterface'

时间:2013-10-07 20:42:46

标签: c# generics recursion interface

public interface INestedInterfaceTest<TChildType>
    where TChildType : INestedInterfaceTest<TChildType>
{
     List<TChildType> children { get; set; }
}

public abstract class NestedInterfaceTest : INestedInterfaceTest<NestedInterfaceTest>
{
    public List<NestedInterfaceTest> children { get; set; }

    public TNestedInterface GetNestedInterface<TNestedInterface>()
        where TNestedInterface : NestedInterfaceTest, new()
    {
        return GateWay<TNestedInterface>.GetNestedInterface();
    }
}

public class GateWay<TNestedInterface>
    where TNestedInterface : class, INestedInterfaceTest<TNestedInterface>, new()
{
    public static TNestedInterface GetNestedInterface()
    {
        return new TNestedInterface();
    }
}

抽象类中的GetNestedInterface方法出错了。 错误消息是:类型'TNestedInterface'必须可转换为'INestedInterfaceTest',以便在泛型类'GateWay'中将其用作参数'TNestedInterface'。

但是......,我的抽象类 NestedInterfaceTest 实现了 INestedInterfaceTest 接口。 我在这里缺少什么?

以下工作正常,没有递归接口实现:

public interface INestedInterfaceTest
{
}

public abstract class NestedInterfaceTest : INestedInterfaceTest
{
    public List<NestedInterfaceTest> children { get; set; }

    public TNestedInterface GetNestedInterface<TNestedInterface>()
        where TNestedInterface : NestedInterfaceTest, new()
    {
        return GateWay<TNestedInterface>.GetNestedInterface();
    }
}

public class GateWay<TNestedInterface>
    where TNestedInterface : class, INestedInterfaceTest, new()
{
    public static TNestedInterface GetNestedInterface()
    {
        return new TNestedInterface();
    }
}

似乎在递归实现中出错了。

3 个答案:

答案 0 :(得分:1)

您在GetNestedInterface<>()上缺少通用约束。将其更改为:

public TNestedInterface GetNestedInterface<TNestedInterface>()
    where TNestedInterface : 
        NestedInterfaceTest, 
        INestedInterfaceTest<TNestedInterface>, // new
        new()
{
    return GateWay<TNestedInterface>.GetNestedInterface();
}

注意第二个约束是新的。

答案 1 :(得分:0)

NestedInterfaceTest实施INestedInterfaceTest<NestedInterfaceTest>,而TNestedInterfaceGetNestedInterface的要求是它应该实施INestedInterfaceTest<TNestedInterface>

如果我创建的NestedInterfaceTest子类没有重新实现INestedInterfaceTest<>接口,则不会满足该约束:

//does not implement INestedInterfaceTest<Derived>
class Derived : NestedInterfaceTest {}
class Derived2 : NestedInterfaceTest {}

Derived d = new Derived();
// breaks because GateWay<Derived2> cannot be constructed
d.GetNestedInterface<Derived2>();

我认为,最简单的解决方法是,可能不适合您的对象模型的是使用以下内容重新定义GateWay类的约束:

public class GateWay<TNestedInterface>
  where TNestedInterface : class, INestedInterfaceTest<NestedInterfaceTest>, new()

这样,任何继承自NestedInterfaceTest的类都将满足约束而无需重新实现接口,因为NestedInterfaceTest实现了它。它可能更容易做到:

public class GateWay<TNestedInterface>
  where TNestedInterface : class, NestedInterfaceTest, new()

无论如何,即使你设法让它工作,它仍然令人困惑,无论是对于类的消费者,还是对于(最终的)维护者。此外,您几乎永远不会确定会发生一些误用not be possible

答案 2 :(得分:0)

我想我解决了自己的问题。 请查看代码并告诉我您的想法:

public interface INestedInterfaceTest<TChildType>
    where TChildType : INestedInterfaceTest<TChildType>
{
    List<TChildType> children { get; set; }
}

public abstract class NestedInterfaceTest<TChildNestedInterface> : INestedInterfaceTest<TChildNestedInterface>
    where TChildNestedInterface : INestedInterfaceTest<TChildNestedInterface>
{
    public List<TChildNestedInterface> children { get; set; }

    public virtual TNestedInterface GetNestedInterface<TNestedInterface>()
        where TNestedInterface : NestedInterfaceTest<TChildNestedInterface>, INestedInterfaceTest<TNestedInterface>, new()
    {
        return GateWay<TNestedInterface>.GetNestedInterface();
    }
}

public class GateWay<TNestedInterface>
    where TNestedInterface : class, INestedInterfaceTest<TNestedInterface>, new()
{
    public static TNestedInterface GetNestedInterface()
    {
        List<TNestedInterface> nestedChildren = new List<TNestedInterface>();
        return new TNestedInterface
            {
                children = nestedChildren
            };
    }
}

public class NestedClass : NestedInterfaceTest<NestedClass>
{
    public NestedClass GetNestedClass()
    {
        return GetNestedInterface<NestedClass>();
    }
}

这样做很好,它可以防止界面'漏出'。