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

2 に答える 2

6

これは共分散とは関係ありません。それはただ不可能です。

TSを拡張する任意のクラスになる可能性があるため、基本インスタンスをSavedState魔法のように変換することはできません。SavedStateTS

たとえば、 を作成すると、コードは基本オブジェクトをBoxGroup<MySpecialSavedState>に変換しようとしますが、これは不可能です。SavedStateMySpecialSavedState

于 2011-01-05T02:10:40.733 に答える
2

これは、あなたが望むものを試して達成するための1つの潜在的な方法を示す小さなプログラムです:

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 から派生したすべての型にはデフォルトのコンストラクターが必要です) とオブジェクト初期化子を使用するという考え方です。もちろん、これは、SaveState クラスがプライベート セッターを持つことができなくなったことを意味します。

于 2011-01-05T02:18:58.400 に答える