Когда реализация интерфейса, которые определяют свойство базового класса, почему реализация класса не может взаимодействовать через интерфейс, возвращает текстовый объект производного класса?

Позволяет создают некоторые интерфейсы

public interface ITimeEventHandler
    {
        string Open();
    }

    public interface IJobTimeEventHandler : ITimeEventHandler
    {
        string DeleteJob();
    }

    public interface IActivityTimeEventHandler : ITimeEventHandler
    {
        string DeleteActivity();
    }



    public interface ITimeEvent
    {
        ITimeEventHandler Handler { get; }
    }

    public interface IJobTimeEvent : ITimeEvent
    {
        int JobID { get;  }
    }

Создайте класс

public class JobTimeEvent : IJobTimeEvent
    {
        public int JobID
        {
            get; internal set;

        }

        public IJobTimeEventHandler Handler
        {
            get; internal set;
        }

    }

Мой вопрос.. при реализации интерфейса, которые определяют свойство базового класса, почему наклон интерфейс реализации класса возвращает текстовый объект производного класса??

Поскольку исключая в классе JobTimeEvent, IJobtimeEvent нужно свойство типа ITimeEventHandler, но почему тип IJobTimeEventHandler не позволяется, который произошел из ITimeEventHandler

5
задан Cœur 6 August 2017 в 16:27
поделиться

4 ответа

Это дублирует

Почему C # не допускает наследование возвращаемого типа, когда реализация интерфейса

. Нужная вам функция называется «ковариацией возвращаемого типа», и это часто запрашиваемая функция в C #. Он не поддерживается CLR, и мы не планируем реализовывать его на C #, извините!

7
ответ дан 14 December 2019 в 01:05
поделиться

Если вы хотите, чтобы поля, которые вы определили, действительно были свойствами вы могли бы сделать что-то вроде этого ...

public interface ITimeEvent
{
    ITimeEventHandler Handler { get; set; }
}
public interface IJobTimeEvent : ITimeEvent
{
    int JobID { get; set; }
}

public class JobTimeEvent : IJobTimeEvent
{
    public JobTimeEvent()
    {
        //these are currently useless because they are the default values
        this.JobID = 0;
        this.Handler = null;
    }
    public int JobID { get; set; }
    public ITimeEventHandler Handler { get; set; }
}

... если вы пытаетесь сделать что-то другое, вам нужно будет предоставить более подробную информацию по вашему вопросу.

0
ответ дан 14 December 2019 в 01:05
поделиться

Он может возвращать класс этого типа, но он должен удовлетворять условиям контракта интерфейса ITimeEvent и возвращать его с указанием типа ITimeEventHandler . Предлагаем вам использовать свойство этого типа с дополнительным полем производного типа.

0
ответ дан 14 December 2019 в 01:05
поделиться

Редактировать: Следующее в равной степени справедливо для свойств get / set, поэтому тот факт, что вы не можете объявлять поля в интерфейсе, не является основополагающим для моих замечаний.

В вашем случае ITimeEvent.Handler - это поле, что означает, что вы можете сделать следующее:

ITimeEvent x = ...;
IJobTimeEventHandler handler = ...;
x.Handler = handler;

Если x был назначен объект (конкретный) тип ] JobTimeEvent и JobTimeEvent.Handler были объявлены как JobTimeEventHandler , то указанное выше присвоение завершится ошибкой. Это пример того, как контравариантность небезопасна для присваивания.

Если бы вместо этого у вас было следующее:

interface ITimeEvent
{
    IJobTimeEventHandler Handler { get; }
}

Тогда вы могли бы легко сделать это:

class JobTimeEvent : ITimeEvent
{
    private JobTimeEventHandler _handler;

    public IJobTimeEventHandler Handler { get { return _handler; } }
}
2
ответ дан 14 December 2019 в 01:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: