繁体   English   中英

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

[英]When implementing an interface which define a base class property why can't the class implementing interface return a derived class type object?

让我们创建一些接口

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类型

这是重复的

为什么C#在实现接口时不允许继承返回类型

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

编辑:以下内容同样适用于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; } }
}

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM