Ошибка преобразования, когда ее не должно быть, поскольку класс реализует требуемый интерфейс - PullRequest
0 голосов
/ 03 мая 2018

У меня интерфейс выглядит следующим образом:

public interface IPageViewModel<T> where T : class
{
    string ViewName { get; set; }
    T SelectedItem { get; set; }
    List<T> ItemsList { get; set; }
}

Тогда у меня есть два класса:

internal class TestViewModel : IPageViewModel<INotifyPropertyChanged> //let's skip the fact that T is supposed to be a class while it somehow compiles and works with an interface...

internal class HardwareViewModel : IPageViewModel<Hardware>

Где Hardware:

public class Hardware : NotificationObject

А NotificationObject - это:

public class NotificationObject : INotifyPropertyChanged

И, наконец, у меня есть следующий класс:

internal class NavigationViewModel
{
    public List<IPageViewModel<INotifyPropertyChanged>> PageViewModelsList { get; set; } = new List<IPageViewModel<INotifyPropertyChanged>>();

    public NavigationViewModel()
    {
        PageViewModelsList.Add(new TestViewModel());
        PageViewModelsList.Add(new HardwareViewModel()); //error
    }
}

Теперь проблема в том, что в то время как первая строка в конструкторе компилируется нормально, вторая выдает ошибку: cannot convert from ViewModels.HardwareViewModel to Helpers.IPageViewModel<System.Component.INotifyPropertyChanged>.
Но это не имеет смысла. Hardware наследуется от NotificationObject, который реализует INotifyPropertyChanged, поэтому IPageViewModel<Hardware> === IPageViewModel<INotifyPropertyChanged>. Может кто-нибудь объяснить, почему есть ошибка?

1 Ответ

0 голосов
/ 06 мая 2018

Благодаря комментариям я понял, что тема, вызывающая эти проблемы, называется «дисперсия». Поэтому, прочитав немного об этом, я решил пойти с этим решением:

public interface IPageViewModel
{
    string ViewName { get; set; }
}

Но если бы кто-то хотел сохранить эти поля и сохранить их интерфейсы ковариантными, он должен был бы выглядеть примерно так:

public interface IPageViewModel<out T> where T : class
{
    string ViewName { get; set; }
    T SelectedItem { get; }
    IEnumerable<T> ItemsList { get; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...