When implementing an interface that defines a property of a base class, why can't the class implementation interface return an object of type a derived class?

Allows you to create some interfaces

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

Create class

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

My question is .. when implementing an interface that defines a property of a base class, why can not the class implementation interface return an object of type a derived class?

For ex in the JobTimeEvent class for IJobtimeEvent, a property of type ITimeEventHandler is required, but why the type IJobTimeEventHandler is not valid, which is obtained from ITimeEventHandler

+4
source share
4 answers

This is a duplicate

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

The function you want is called "return type covariance," and it is a frequently requested function in C #. It is not supported by the CLR, and we do not plan to implement it in C #, sorry!

+5
source

Edit:. The following values ​​are the same for the get / set properties, so the fact that you cannot declare fields in an interface is not fundamental to the points I make.

In your case, ITimeEvent.Handler is a field, which means you can do the following:

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

If x was assigned an object (specific) of type JobTimeEvent , and JobTimeEvent.Handler was declared as JobTimeEventHandler , the assignment above failed. This is an example of how contravariance is not a safe operation to assign.

If instead you had the following:

 interface ITimeEvent { IJobTimeEventHandler Handler { get; } } 

Then you can easily do this:

 class JobTimeEvent : ITimeEvent { private JobTimeEventHandler _handler; public IJobTimeEventHandler Handler { get { return _handler; } } } 
+2
source

It can return a class of this type, but must satisfy the contract of the ITimeEvent interface and return it by specifying its type ITimeEventHandler . Suggest using a property of this type with a feedback field of a derived type.

0
source

If you want the fields you were tagged to really be properties, you could do something like this ...

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

... If you are trying to do something else, you will need to provide more detailed information on your subject.

0
source

Source: https://habr.com/ru/post/1305787/


All Articles