Reputation: 1825
Have stepped on my own toes with what I thought was a very simple piece of code. Code speaks better than words, so here it is.
public interface IResponse
{
IResult Result { get; set; }
}
public class Response<T> : IResponse
where T : IResult
{
public T Result { get; set; }
// COMPILER ERROR: Property 'Result' cannot be implemented property from interface 'IResponse'. Type should be 'IResult'.
}
The compiler does not allow me to do this because IResponse requires Result to be IResult, however I want to take advantage of generics in the implementing class and strongly type the result to T. Is this just not possible, or have I missed something trivial?
Upvotes: 8
Views: 2214
Reputation: 29632
They you have to make IResponse
generic too:
public interface IResponse<T>
where T : IResult
{
T Result { get; set; }
}
public class Response<T> : IResponse<T>
where T : IResult
{
public T Result { get; set; }
}
If you want to keep the IResponse
interface without the generic parameter in tact, you can go even fancier. The below has the two interfaces, where the class transparently also implements the interface without the generic parameter:
public interface IResponse
{
IResult Result { get; set; }
}
public interface IResponse<T> : IResponse
where T : IResult
{
T Result { get; set; }
}
public class Response<T> : IResponse<T>
where T : IResult
{
public T Result { get; set; }
IResult IResponse.Result
{
get { return Result; }
set { Result = (T)value; }
}
}
And, if you want to stay closer to your original implementation, you can strip out the IResponse<T>
and get the following:
public interface IResponse
{
IResult Result { get; set; }
}
public class Response<T> : IResponse
where T : IResult
{
public T Result { get; set; }
IResult IResponse.Result
{
get { return Result; }
set { Result = (T)value; }
}
}
Upvotes: 12
Reputation: 21
Try this
public class Response<T> : IResponse
where T : IResult
{
public T Result { get; set; }
// COMPILER ERROR: Property 'Result' cannot be implemented property from interface 'IResponse'. Type should be 'IResult'.
IResult IResponse.Result
{
get { return this.Result; }
set { this.Result = (T)value; }
}
}
Upvotes: 2
Reputation: 65274
public interface IResponse<T> where T : IResult
{
T Result { get; set; }
}
public class Response<T> : IResponse<T> where T : IResult
{
public T Result { get; set; }
// NO MORE COMPILER ERROR
}
Upvotes: 1
Reputation: 273219
If you 'just' want to "take advantage of generics" you don't need IResponse
.
The interface is solving another problem, one that is not compatible with your wish. Consider
IResponse r = x ? new Response<int>() : new Response<string>();
r.Result = ... // what type?
So either make IResponse
generic too or remove it altogether.
Upvotes: 4
Reputation: 5605
You should make IResponse generic and change type of Result in IResponse as type paramter passed to this interface.
public interface IResponse<T> where T : IResult
{
T Result { get; set; }
}
public class Response<T> : IResponse<T>
{
public T Result { get; set; }
}
Upvotes: 1