2011-01-05 80 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