Reputation: 17844
I have got class declared like this:
internal private abstract class BoxGroup<TS> : IBoxGroup where TS : SavedState
In that class I have this method:
protected virtual TS saveState() {
return new SavedState(Width, Height);
}
I thought that this will be correct but I see red line under return statement and Resharper says that new SavedState(Width, Height)
cannot be converted to TS
. I don't know why. I thought that TS
can be any class that extends SavedState
but also SavedState
itself. What can I do to correct it ?
Class saved state is very simple it looks like this:
private class SavedState {
internal float Width { get; private set; }
internal float Height { get; private set; }
public SavedState(float width, float height) {
Width = width;
Height = height;
}
}
Upvotes: 2
Views: 194
Reputation: 888185
This has nothing to do with covariance; it's just impossible.
Since TS
can be any class that extends SavedState
, you cannot magically convert a base SavedState
instance to whatever TS
is.
For example, if I make a BoxGroup<MySpecialSavedState>
, your code will try to convert a base SavedState
object to a MySpecialSavedState
, which is not possible.
Upvotes: 6
Reputation: 5404
Here's a small program illustrating one potential way to try and achieve what you want:
using System;
namespace Test
{
class SaveState
{
public int Width { get; set; }
public int Height { get; set; }
}
class SaveStateWithPi : SaveState
{
public double Pi
{
get { return Math.PI; }
}
}
class Program
{
public static T CreateSavedState<T>(int width, int height)
where T : SaveState, new()
{
return new T
{
Width = width,
Height = height
};
}
static void Main(string[] args)
{
SaveState state = CreateSavedState<SaveStateWithPi>(5, 10);
Console.WriteLine("Width: {0}, Height: {1}", state.Width, state.Height);
}
}
}
Basically the idea is to use a new() constraint (thus all of your types derived from SaveState must have a default constructor) and object initializers. Of course this does mean that your SaveState class can't have private setters anymore.
Upvotes: 2