实现定义基类属性的接口时,为什么类实现接口不能返回派生类类型对象?

时间:2010-04-01 17:34:01

标签: c# inheritance

让我们创建一些接口

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中的ex,IJobtimeEvent需要一个ITimeEventHandler类型的属性,但为什么不允许从IimeEventHandler派生的IJobTimeEventHandler类型

4 个答案:

答案 0 :(得分:7)

这是

的副本

Why C# doesn't allow inheritance of return type when implementing an Interface

您想要的功能称为“返回类型协方差”,它是C#中经常请求的功能。 CLR不支持它,我们没有计划在C#中实现它,抱歉!

答案 1 :(得分:2)

编辑:以下内容同样适用于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 :(得分:0)

它可以返回这种类型的类,但它必须满足ITimeEvent接口的约定并返回它,说它是类型ITimeEventHandler。建议您使用此类型的属性,并使用派生类型的支持字段。

答案 3 :(得分:0)

如果你想要你定义的字段真的是属性,你可以做这样的事情......

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; }
}

...如果您尝试做一些不同的事情,您需要提供更多详细信息。