[英]Covariance issue in C#
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
. 我认为这是正确的,但我在return语句下看到红线,Resharper说new SavedState(Width, Height)
无法转换为TS
。 I don't know why. 我不知道为什么。 I thought that TS
can be any class that extends SavedState
but also SavedState
itself. 我认为TS
可以是任何扩展SavedState
类,也可以是SavedState
本身。 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;
}
}
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. 由于TS
可以是任何扩展SavedState
类, SavedState
您无法将基本SavedState
实例神奇地转换为TS
。
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. 例如,如果我创建一个BoxGroup<MySpecialSavedState>
,您的代码将尝试将基本SavedState
对象转换为MySpecialSavedState
,这是不可能的。
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. 基本上,我们的想法是使用new()约束(因此从SaveState派生的所有类型都必须具有默认构造函数)和对象初始值设定项。 Of course this does mean that your SaveState class can't have private setters anymore. 当然这意味着你的SaveState类不能再拥有私有的setter了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.