2013-06-05 62 views
4

这是我想做的那种东西:自参照接口

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

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

我试过这个,但是我不能得到实现类来正确实现该方法。

+0

可能与通用/模板耦合,这将让你达到你的目标。 – Serge

+3

请不要在一个中发布两个相对不相关的问题。序列化确实与接口定义没有任何关系。 –

+0

你应该使用IList而不是列表 –

回答

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

实现此接口是直截了当:

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 }; 
    } 
} 
+2

[奇怪的循环模板模式]的好用例(http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern);) –

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

在某种意义上,你需要创建一个没有父母,有的人(某种亚当和夏娃的),然后通过持有引用到自己的父母增添孩子的。正如你所看到的,我的天真模型可以处理随机深度的家庭结构,同时还有非常简单的界面暴露在外面。

1

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

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

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