Могут ли полученные свойства интерфейса С# переопределять свойства базового интерфейса с тем же именем?
Я пытаюсь создать систему наследования интерфейса, которая использует одно и то же свойство, но всегда имеет следующий производный тип. Таким образом, базовое свойство должно быть каким-то образом переопределено или скрыто интерфейсом вывода.
Возьмем, к примеру, два интерфейса: "Человек и женщина", которые происходят с мужем и женой, также взаимодействуют. Интерфейсы "человек и муж" имеют оба свойства "возлюбленной" , а "Женщина и жена" - "дорогая" собственность. Теперь, человек "возлюбленной" собственности имеет тип Женщина, в то время как муж такой же "возлюбленной" собственности должен быть Жена (полученная от Женщины). И то же самое с женской и женской "дорогой" собственностью.
public interface Man // base interface for Husband
{
Woman sweetheart { get; set; }
}
public interface Woman // base interface for Wife
{
Man darling { get; set; }
}
public interface Husband : Man // extending Man interface
{
new Wife sweetheart { get; set; } // narrowing "sweetheart" property type
}
public interface Wife : Woman // extending Woman interface
{
new Husband darling { get; set; } // narrowing "darling" property type
}
public class RandomHusband : Husband // implementing the Husband interface
{
private RandomWife wife;
public Wife sweetheart { get { return wife; } set { wife = value; } }
}
public class RandomWife : Wife // implementing the Wife interface
{
private RandomHusband husband;
public Husband darling { get { return husband; } set { husband = value; } }
}
Этот код неправильный, он не работает. Я не уведомлен о том, что я не реализовал основные свойства Man.sweetheart
и Woman.darling
, и что реализованные Husband.sweetheart
и Wife.darling
не будут выполняться, потому что типы не совпадают. Есть ли способ сужения типа свойства на производный? Как вы его достигаете на С#?
Ответы
Ответ 1
вам все равно придется устраивать интерфейсы "Человек и Женщина", а также "Муж и жена"...
public class RandomWife : Wife // implementing the Wife interface
{
private RandomHusband husband;
public Husband darling { get { return husband; } set { husband = value; } }
public Man Wife.darling { get { return husband; } set { /* can't set anything */ } }
}
Ответ 2
Вы можете сделать это, задав параметры интерфейсов Man
и Woman
с конкретными типами реализации:
public interface IMan<M, W>
where M : IMan<M, W>
where W : IWoman<W, M>
{
W Sweetheart { get; set; }
}
public interface IWoman<W, M>
where W : IWoman<W, M>
where M : IMan<M, W>
{
M Darling { get; set; }
}
Ваши реализации:
public class Man : IMan<Man, Woman>
{
public Woman Sweetheart { get; set; }
}
public class Woman : IWoman<Woman, Man>
{
public Man Darling { get; set; }
}
public class Husband : IMan<Husband, Wife>
{
public Wife Sweetheart { get; set; }
}
public class Wife : IWoman<Wife, Husband>
{
public Husband Darling { get; set; }
}
Поскольку типы становятся довольно сложными, вам может потребоваться переместить отношения во внешний класс/интерфейс:
public interface Relationship<TMan, TWoman>
where TMan : Man
where TWoman : Woman
{
TMan Darling { get; }
TWoman Sweetheart { get; }
}
public class Marriage : Relationship<Husband, Wife>
{
}
Затем вы можете использовать этот класс для сохранения безопасности типов при работе с конкретными реализациями:
public static void HandleMarriage(Relationship<Husband, Wife> marriage)
{
Husband h = marriage.Darling;
Wife w = marriage.Sweetheart;
}