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了