Self referencing interface

后端 未结 4 1954
眼角桃花
眼角桃花 2021-01-18 05:15

This is the kind of thing I want to do:

Interface IMyInterface
{
    List GetAll(string whatever)
}

so that classes imp

相关标签:
4条回答
  • 2021-01-18 05:32

    Implementing this interface is straight forward:

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

    Please note that the method signature needs to be exactly the same, i.e. the return type has to be List<IMyInterface> and not List<MyInterfaceImpl>.

    If you want the type in the list to be the same type as the class that implements the interface, you will have to use generics:

    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 };
        }
    }
    
    0 讨论(0)
  • 2021-01-18 05:33

    This works for me:

    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);
        }
    }
    
    0 讨论(0)
  • 2021-01-18 05:46

    This is a normal solution. Consider you have interface IPerson and you want to access each parent of a person. So it would be reasonable to have interface declaration as following:

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

    Now you are able to get parents of that parents and then get parents... Hope you got the idea. Such design is very flexible, because it allows to model deep dynamic structures using simple static models.

    Implementation is very straight-forward:

    class Person : IPerson
    {
        IList<IPerson> parents;
    
        public Person(IList<IPerson> parents)
        {
            this.parents = parents;
        }
    
        public IList<IPerson> GetAllParents()
        {
            return parents;
        }
    }
    

    In some sense you need to create some Persons without parents (some kind of Adam and Eve) and then add childs by holding references to their parents. As you can see, my naive model can handle randomly deep family structures, while having very simple interface exposed outside.

    0 讨论(0)
  • 2021-01-18 05:50

    I don't see why interface could not reference itself - no problem with below.

    interface ITest
    {
        List<ITest> GetAll(string whatever);
    }
    
    class MyClass : ITest
    {
        public List<ITest> GetAll(string whatever)
        {
            return new List<ITest>();
        }
    }
    
    0 讨论(0)
提交回复
热议问题