Подтвердить что ты не робот

Могут ли полученные свойства интерфейса С# переопределять свойства базового интерфейса с тем же именем?

Я пытаюсь создать систему наследования интерфейса, которая использует одно и то же свойство, но всегда имеет следующий производный тип. Таким образом, базовое свойство должно быть каким-то образом переопределено или скрыто интерфейсом вывода.

Возьмем, к примеру, два интерфейса: "Человек и женщина", которые происходят с мужем и женой, также взаимодействуют. Интерфейсы "человек и муж" имеют оба свойства "возлюбленной" , а "Женщина и жена" - "дорогая" собственность. Теперь, человек "возлюбленной" собственности имеет тип Женщина, в то время как муж такой же "возлюбленной" собственности должен быть Жена (полученная от Женщины). И то же самое с женской и женской "дорогой" собственностью.

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 не будут выполняться, потому что типы не совпадают. Есть ли способ сужения типа свойства на производный? Как вы его достигаете на С#?

4b9b3361

Ответ 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;
}