自引用界面

时间:2013-06-05 09:14:11

标签: c# xml interface

这是我想要做的事情:

Interface IMyInterface
{
    List<IMyInterface> GetAll(string whatever)
}

这样实现它的类必须有一个返回自己类型列表的函数。 这甚至可能吗? 我知道 - 技术上 - 实现这个的类可以返回实现它的其他类的列表,不一定是同一个类,但我可以忍受它,即使它不是理想的。

我试过这个,但我无法让实现类正确实现该方法。

4 个答案:

答案 0 :(得分:11)

直接实现此界面:

public class MyInterfaceImpl : IMyInterface
{
    public List<IMyInterface> GetAll(string whatever)
    {
        return new List<IMyInterface> { new MyInterfaceImpl(), this };
    }
}

请注意,方法签名必须完全相同,即返回类型必须为List<IMyInterface>而不是List<MyInterfaceImpl>

如果希望列表中的类型与实现接口的类相同,则必须使用泛型:

public interface IMyInterface<T> where T : IMyInterface<T>
{
    List<T> GetAll(string whatever)
}

public class MyInterfaceImpl : IMyInterface<MyInterfaceImpl>
{
    public List<MyInterfaceImpl> GetAll(string whatever)
    {
        return new List<MyInterfaceImpl > { new MyInterfaceImpl(), this };
    }
}

答案 1 :(得分:2)

这是正常的解决方案。考虑您有接口IPerson,并且您想要访问某个人的每个父级。所以将接口声明如下是合理的:

interface IPerson
{
    IList<IPerson> GetAllParents();
}

现在你能够得到那些父母的父母,然后得到父母......希望你明白了。这种设计非常灵活,因为它允许使用简单的静态模型对深层动态结构进行建模。

实施非常简单:

class Person : IPerson
{
    IList<IPerson> parents;

    public Person(IList<IPerson> parents)
    {
        this.parents = parents;
    }

    public IList<IPerson> GetAllParents()
    {
        return parents;
    }
}

在某种意义上,你需要创建一些没有父母的人(某种亚当和夏娃),然后通过引用他们的父母来添加孩子。正如您所看到的,我的天真模型可以处理随机深层的族结构,同时在外部暴露出非常简单的界面。

答案 2 :(得分:1)

我不明白为什么界面无法引用自己 - 下面没有问题。

interface ITest
{
    List<ITest> GetAll(string whatever);
}

class MyClass : ITest
{
    public List<ITest> GetAll(string whatever)
    {
        return new List<ITest>();
    }
}

答案 3 :(得分:1)

这对我有用:

public interface IMyInterface
{
    List<IMyInterface> GetAll(string whatever);
}

public class Program : IMyInterface
{
    public string Member { get; set; }

    public List<IMyInterface> GetAll(string whatever)
    {
        return new List<IMyInterface>()
            { new Program() { Member = whatever } };
    }

    static void Main(string[] args)
    {
        List<IMyInterface> all = new Program().GetAll("whatever");
        Console.WriteLine(all.Count);
    }
}