C# C语言中的协方差问题#
我已将类声明如下:C# C语言中的协方差问题#,c#,generics,covariance,contravariance,C#,Generics,Covariance,Contravariance,我已将类声明如下: internal private abstract class BoxGroup<TS> : IBoxGroup where TS : SavedState private class SavedState { internal float Width { get; private set; } internal float Height { get; private set; } public SavedState(float widt
internal private abstract class BoxGroup<TS> : IBoxGroup where TS : SavedState
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;
}
}
我认为这是正确的,但我在return语句下看到红线,Resharper说新的SavedState(宽度、高度)
不能转换为TS
。我不知道为什么。我认为TS
可以是任何扩展SavedState
的类,也可以是SavedState
本身的类。我能做些什么来纠正它
类保存状态非常简单,如下所示:
internal private abstract class BoxGroup<TS> : IBoxGroup where TS : SavedState
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;
}
}
这与协方差无关;这是不可能的 由于
TS
可以是扩展SavedState
的任何类,因此不能将基本SavedState
实例神奇地转换为TS
所属的任何类
例如,如果我创建了一个
BoxGroup
,您的代码将尝试将基本SavedState
对象转换为MySpecialSavedState
,这是不可能的。下面是一个小程序,演示了一种尝试并实现所需的潜在方法:
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);
}
}
}
使用系统;
名称空间测试
{
类存储状态
{
公共整数宽度{get;set;}
公共整数高度{get;set;}
}
类SaveStateWithPi:SaveState
{
公共双Pi
{
获取{return Math.PI;}
}
}
班级计划
{
公共静态T CreateSavedState(整数宽度、整数高度)
其中T:SaveState,new()
{
返回新的T
{
宽度=宽度,
高度=高度
};
}
静态void Main(字符串[]参数)
{
SaveState=CreateSavedState(5,10);
WriteLine(“宽度:{0},高度:{1}”,state.Width,state.Height);
}
}
}
基本上,这个想法是使用一个新的()约束(因此从SaveState派生的所有类型都必须有一个默认构造函数)和对象初始值设定项。当然,这意味着您的SaveState类不能再有私有setter了