2011-01-05 77 views
2

我有一个类中声明是这样的:协方差问题

internal private abstract class BoxGroup<TS> : IBoxGroup where TS : SavedState 

那堂课我有这样的方法:

protected virtual TS saveState() { 
    return new SavedState(Width, Height); 
} 

我认为这将是正确的,但我看到在红线return语句和Resharper说new SavedState(Width, Height)无法转换为TS。我不知道为什么。我认为TS可以是任何延伸SavedState的类别,也可以是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; 
    } 
} 

回答

2

这里的说明,试图实现你想要的一个潜在方法的一个小程序:

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); 
     } 
    } 
} 

基本的想法是使用new()约束(因此,所有从即时存档派生的类必须有一个默认构造函数)和对象初始值设定项。当然,这意味着你的SaveState类不能再有私人设置者了。

6

这有什么好做的协方差;这是不可能的。

由于TS可以是任何延伸SavedState的类,所以您不能神奇地将基地SavedState实例转换为任何TS

例如,如果我制作一个BoxGroup<MySpecialSavedState>,您的代码将尝试将基本SavedState对象转换为MySpecialSavedState,这是不可能的。

+0

明白了......我很愚蠢。 – drasto 2011-01-05 02:13:06