Reputation: 117
Lets 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 a class
public class JobTimeEvent : IJobTimeEvent
{
public int JobID
{
get; internal set;
}
public IJobTimeEventHandler Handler
{
get; internal set;
}
}
My question is .. when implementing an interface which define a base class property why cant the class implementing interface return a derived class type object ??
For ex in class JobTimeEvent, IJobtimeEvent needs a property of type ITimeEventHandler but why IJobTimeEventHandler type is not allowed which derived from ITimeEventHandler
Upvotes: 5
Views: 2893
Reputation: 659956
This is a duplicate of
Why C# doesn't allow inheritance of return type when implementing an Interface
The feature you want is called "return type covariance", and it is a frequently requested feature in C#. It is not supported by the CLR and we have no plans to implement it in C#, sorry!
Upvotes: 7
Reputation: 22433
If you want the fields you definded 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 different you will need to provide more details to your question.
Upvotes: 0
Reputation: 99859
Edit: The following is equally valid for get/set properties, so the fact that you can't declare fields in an interface is not fundamental to the points I'm making.
In your case, ITimeEvent.Handler
is a field, which means you could do the following:
ITimeEvent x = ...;
IJobTimeEventHandler handler = ...;
x.Handler = handler;
If x
was assigned an object of (concrete) type JobTimeEvent
, and JobTimeEvent.Handler
was declared as a JobTimeEventHandler
, the the assignment above would fail. This is an example of how contravariance is not a safe operation for assignment.
If instead you had the following:
interface ITimeEvent
{
IJobTimeEventHandler Handler { get; }
}
Then you could easily do this:
class JobTimeEvent : ITimeEvent
{
private JobTimeEventHandler _handler;
public IJobTimeEventHandler Handler { get { return _handler; } }
}
Upvotes: 2
Reputation: 72840
It can return a class of this type, but it must satisfy the contract of the ITimeEvent
interface and return it saying it's of type ITimeEventHandler
. Suggest you use a property of this type, with a backing field of the derived type.
Upvotes: 0