tags:

views:

116

answers:

4

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

A: 

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.

David M
+2  A: 

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; } }
}
280Z28
A: 

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.

Matthew Whited
+3  A: 

This is a duplicate of

http://stackoverflow.com/questions/1319663/why-c-doesnt-allow-inheritance-of-return-type-when-implementing-an-interface/1320710#1320710

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!

Eric Lippert