Общий интерфейс - PullRequest
       44

Общий интерфейс

1 голос
/ 02 февраля 2012

Я разрабатываю приложение, в котором похожие объекты находятся в двух местах с разными типами сбора, как показано ниже.

Модель:

class PersonModel {
  public string Name { get;set;}
  public List<Address> Addresses { get;}
  public List<OtherType> OtherTypes { get;}
}

Аналогичная модель:

class PersonViewModel {
   public string Name { get;set;}
   public ObservableCollection<Address> Addresses { get; }
   public ObservableCollection<OtherType> OtherTypes { get; }
}

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

public interface IPerson<T> where T: ICollection<T> {
   string Name { get;set;}
   T<Address> Addresses { get;}
   T<OtherType> OtherTypes [ get; } 
}

и классы будут

class PersonModel<List> {}
class personViewModel<ObservableCollection> {}

но компилятор не готов к компиляции моего интерфейса. :( Говорит, что параметр типа "T" нельзя использовать с аргументом типа.

Причину, по которой я этого хочу, я хотел минимизировать преобразование типов из / в модель и viewModel.

Моя viewModel будет такой,

class PersonViewModel<T> : IPerson<T> {
   public PersonViewModel(IPerson model){
      this.Model = model;
   }
   internal PersonModel Entity {
      get; set;
   }
   public string Name { 
      get{ return model.Name;} 
      set {model.Name = value;}
   }
   public T<Address> Addresses {
      get { return model.Addresses.Cast<T>(); }
   }
}

Предложите лучший способ синхронизации Model & ViewModel.

Ответы [ 4 ]

1 голос
/ 02 февраля 2012

Ваши реализации должны выглядеть следующим образом:

class PersonModel : IPerson<List> {}
class PersonViewModel : IPerson<ObservableCollection> {}

Вам действительно нужен общий класс? ObservableCollection<T> и List<T> оба реализуют ICollection<T>, поэтому вы можете объявить адреса и другие типы в вашем интерфейсе как ICollection<Address> и ICollection<OtherType> соответственно.

(что такое AddressView?)

1 голос
/ 02 февраля 2012

ViewModel существует для предоставления данных для View.Это означает, что это должно быть смоделировано после требований Представления.Обычно эти требования не совпадают с требованиями для Модели.Это означает, что обычно ваша Модель и ваша ViewModel не будут синхронизированы, они будут отличаться.В вашем подходе ViewModel не добавляет никакого значения и может быть удален.

Для отображения между ViewModel и моделью вы можете использовать AutoMapper .

0 голосов
/ 02 февраля 2012

Ваше общее ограничение на IPerson требует, чтобы T реализовал ICollection из T? Это бесконечно рекурсивно, что недопустимо.

Вы также не можете указать универсальные параметры для универсальных типов, поэтому T<Address> не допускается, потому что неизвестно, является ли T универсальным типом или нет.

Вы можете изменить свой интерфейс на следующий:

public interface IPerson<TAddressCol, TOtherCol> 
   where TAddressCol: ICollection<Address>
   where TOtherCol : ICollection<OtherType> 
{
   string Name { get;set;}
   TAddressCol Addresses { get;}
   TAddressCol OtherTypes [ get; } 
}

Тогда используйте это так:

class PersonModel<List<Address>, List<OtherType>> {}
class personViewModel<ObservableCollection<Address>, ObservableCollection<OtherType>> {}

Я думаю, что это единственный реальный способ получить подход, который вы хотите. Но я бы сказал, что ваш интерфейс просто возвращает ICollection<Address> и ICollection<OtherType>. Ваша модель / модель представления должна будет затем представить коллекции через интерфейс, однако ничто не мешает вам иметь поддержку реализации как List или ObservableCollection соответственно.

0 голосов
/ 02 февраля 2012

Вы не можете использовать дженерики таким образом. Вы можете попробовать что-то вроде этого

public interface IPerson
{
    string Name { get; set; }
    ICollection<Address> Addresses { get; }
    ICollection<OtherType> OtherTypes { get; }
}

public class OtherType { }
public class Address { }

А потом

class PersonModel : IPerson
{
    public PersonModel()
    {
        Addresses = new List<Address>();
        OtherTypes = new List<OtherType>();
    }

    public string Name { get; set; }
    public ICollection<Address> Addresses { get; private set; }
    public ICollection<OtherType> OtherTypes { get; private set; }
}

class PersonViewModel : IPerson
{
    public PersonViewModel()
    {
        Addresses = new ObservableCollection<Address>();
        OtherTypes = new ObservableCollection<OtherType>();
    }

    public string Name { get; set; }
    public ICollection<Address> Addresses { get; private set; }
    public ICollection<OtherType> OtherTypes { get; private set; }
}
...