Могу ли я использовать интерфейсы для определения базового ожидания? - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть набор моделей, которые в паре с (почти) совпадающими структурами данных в двух больших устаревших проектах;каждый проект находится по обе стороны от API, и поэтому я хотел создать проект «Globals», который мог бы наследоваться обоими для обеспечения некоторой формы согласованности, уменьшения вероятности возникновения пожаров и начала применения программирования для интерфейсов, а не реализаций.

Мой план состоял в том, чтобы использовать интерфейсы для создания своего рода общей основы, которая может наследовать обе, но может немного отклоняться (из-за данных, необходимых с одной стороны, но не с другой), однако я столкнулся с проблемойс использованием их таким образом, когда дело доходит до вложения.

Скажем, у меня есть два интерфейса:

namespace Example.Interfaces
{
    public interface A
    {
        int X { get; set; }
        int Y { get; set; }
    }

    public interface B
    {
        int J { get; set; }
        List<A> KLM { get; set; }
    }
}

Если я хочу использовать это, используйте их в моделях, на которые я буду смотретьделать что-то вроде ниже.

namespace Example.Models
{
    public class Item : A
    {
        int X { get; set; }
        int Y { get; set; }
    }

    public class Container : B
    {
        int J { get; set; }
        List<Item> KLM { get; set; } // Wrong
    }
}

Это точка, в которой мои ожидания оказываются совершенно неверными (плохой дерпазавр, возвращайся в школу!)

В примере выше.В пределах Container я ожидал бы, что смогу определить List<> из Item s (как показано), поскольку они наследуют A;это, очевидно, не тот случай, так как я вижу предупреждения о том, что я должен определить KLM как List<Interfaces.A>.

Если я внесу изменения, рекомендованные Visual Studio, я не смогу затем выполнитьприсваивание типа Item полю KLM, как показано ниже.

var derp = new Container
{
    J = 1
    KLM = new List<Item> { X = 123, Y = 456 }
};

Затем я вижу следующую ошибку

Невозможно неявно преобразовать тип 'Пример.Models.Item 'to' Example.Interfaces.A '

Мои вопросы:

  • Может ли это быть на самом деле или это невозможно из-за потенциальной потериданных, вызванных неявным преобразованием Item в A?
  • Есть ли лучший способ реализации каркаса базовых (общих) полей между двумя проектами с расходящимися моделями?
  • Могу ли я (должен ли я) сделать какой-нибудь кроссовок для этой работы?

1 Ответ

0 голосов
/ 15 ноября 2018

Чтобы заставить его работать, вам нужно изменить интерфейс:

public interface B<T> where T:A
{
    int J { get; set; }
    List<T> KLM { get; set; }
}

Здесь, где условие вашего интерфейса заставляет классы, которые его реализуют, иметь список объектов типа A.

Теперь ваш интерфейс может быть реализован вашим классом:

public class Container : B<Item>
{
   public int J { get; set; }
   public List<Item> KLM { get; set; } 
}

Если вы хотите получить доступ на чтение к интерфейсу B, не зная конкретного типа, вы можете изменить это:

public interface B
{
    int J { get; set; }
    IEnumerable<A> KLM { get; }
}

public interface B<T> : B where T:A
{
    new List<T> KLM { get; set; }
}

И реализация:

public class Container : B<Item>
{
   public int J { get; set; }
   public List<Item> KLM { get; set; } 

   IEnumerable<A> B.KLM => KLM;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...