Я пробовал это раньше, создавая красивые «доменные» интерфейсы, которые вы применяете к объектам всех видов, так что вы можете писать код, который работает на интерфейсе, а не на объекте домена, но вы очень быстро столкнетесь с проблемами,
Для начала, когда класс реализует интерфейс, он должен точно соответствовать типам членов интерфейса. Конечно, и List<T>
, и ObservableCollection<T>
реализуют IEnumerable<T>
, но это не значит, что они оба удовлетворяют декларации этого члена интерфейса.
Так что вам придется реализовать этот конкретный тип. Вы можете сделать это, например, используя явную реализацию интерфейса. Но у члена интерфейса есть как метод получения, так и метод установки:
class DbModel : IModel
{
public List<string> Values {get; set;}
IEnumerable<string> IModel.Values
{
get { return Values; }
set
{
Values = ... // now what?
}
}
}
class ViewModel : IModel
{
public ObservableCollection<string> Values {get; set;}
IEnumerable<string> IModel.Values
{
get { return Values; }
set
{
Values = ... // now what?
}
}
}
Возможно, нужен метод установки, потому что вы хотите, чтобы какой-то общий код мог назначать коллекцию Values
. И IEnumerable<T>
не очень полезен ни для чего, кроме перечисления.
Так что вам придется преобразовать входящий values
в тип, соответствующий классу в установщике. Например Values = values.ToList()
в первом.
И тогда у вас есть вызывающий абонент:
IModel dbModel = new DbModel();
var values = new List<string> { "foo", "bar" };
dbModel.Values = values;
values.Add("baz");
Что будет dbModel.Values
после этого кода? Подсказка: он не будет содержать "baz"
. Не используйте этот подход, он вас укусит.
Забудьте об общем интерфейсе. Определите реальную проблему, которую должен решить интерфейс, и решите ее другим способом.