Interfaces - метод, возвращающий объект типа конкретного класса, реализующего его - PullRequest
0 голосов
/ 26 февраля 2020

Рассмотрим класс:

// partial code for this class
abstract class DataNode : System.IComparable<DataNode>, System.IEquatable<DataNode>, System.Collections.IEnumerable, IDataNode
{
    protected DataNode parent;
    protected int order = System.Int32.MaxValue;

    // ctor
    protected DataNode(DataNode parent, string name)
    {
       modified = new System.Collections.Generic.Dictionary<string, string>();
       original = new System.Collections.Generic.Dictionary<string, string>();
       _parent = parent;
       if (name == null)
       {
           throw new System.ArgumentNullException("name");
       }
       original.Add("name", name);
       _status = Modification_Status.ADDED;
    }

    // methods returning objects of the same type as the class, need to be defined in interface
    public DataNode getParent()
    {
        // return the parent
    }

    public abstract DataNode deepCopy(DataNode parent);
}

Проблема возникает при работе с методами в классе, реализующими этот интерфейс, которые возвращают объекты того же типа, что и класс, как в двух приведенных выше примерах.

Код находится в процессе рефакторинга для модульного тестирования. Часть этого заключается в создании интерфейсов для базовых классов, таких как этот. Интерфейс создается следующим образом:

// partial interface code
public interface IDataNode
{
    // all public methods

    IData_Node deepCopy(IDataNode parent);
    IData_Node getParent();
}

Методы не могут быть объявлены с DataNode в интерфейсе, так как возвращаемый тип менее доступен. Как справиться с этой проблемой?

Редактировать: На самом деле, объявление метода deep_copy с типом возвращаемого значения и параметром как IDataNode вместо DataNode работает, но, похоже, все ссылки на это в коде нуждаются быть измененным.

1 Ответ

1 голос
/ 26 февраля 2020

Обычный способ сделать это так:

public interface IDataNode
{

}

public interface IDataNode<T> : IDataNode where T : IDataNode
{
    T deepCopy(T parent);
    T getParent();
}

abstract class DataNode : IDataNode<DataNode>
{
    public abstract DataNode deepCopy(DataNode parent);

    public DataNode getParent()
    {
        throw new NotImplementedException();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...