1

特定のジェネリック型を別のジェネリック型の定義で使用できない理由がわかりません。

だから私はこれを持っています:

public abstract class MdiWorkspaceController<TWorkItemController, TMdiWorkspaceView, TWorkItemViewFrame, TWorkItemMainView> 
    : ViewableWorkspaceController<TWorkItemController>
    where TMdiWorkspaceView : class, IMdiWorkspaceView<TWorkItemViewFrame, TWorkItemMainView, TWorkItemMainView>
    where TWorkItemViewFrame : class, IWorkItemViewFrame<TWorkItemMainView>
    where TWorkItemMainView : class, IWorkItemMainView
    where TWorkItemController : ViewableWorkItemController{}

そして私は使用しようとしています

  public partial class TabbedWorkspaceView<TWorkItemMainView>
        : KryptonNavigator,
        IMdiWorkspaceView<TabbedWorkItemViewFrame<TWorkItemMainView>, TWorkItemMainView, TWorkItemMainView>
        where TWorkItemMainView : AbstractWorkItemView

以下のように、より具体的な実装 TabbedWorkspaceController の TTabbedWorkspaceView として:

public class TabbedWorkspaceController<TWorkItemController, TTabbedWorkspaceView, TTabbedWorkItemViewFrame, TWorkItemMainView>
    : MdiWorkspaceController<TWorkItemController, TTabbedWorkspaceView, TTabbedWorkItemViewFrame, TWorkItemMainView>
    where TWorkItemController : ViewableWorkItemController
    where TTabbedWorkspaceView : TabbedWorkspaceView<TWorkItemMainView>
    where TTabbedWorkItemViewFrame : TabbedWorkItemViewFrame<TWorkItemMainView>
    where TWorkItemMainView : AbstractWorkItemView

しかし、TTabbedWorkspaceView は変換可能でなければならないというエラーが表示されます

IMdiWorkspaceView<TTabbedWorkItemViewFrame<TWorkItemMainView>, TWorkItemMainView, TWorkItemMainView>

ジェネリック クラスのパラメータ TMdiWorkspaceView として使用するため

 MdiWorkspaceController<TWorkItemController, TTabbedWorkspaceView, TTabbedWorkItemViewFrame, TWorkItemMainView>

今、私は「賢い」コードの個人的な境界にいることを喜んで認めますが、この後はすべてが完全に具体的になり、アプリケーションレベルで単純化されるので、私が持っているデザインを使い続けたいと思います.

アップデート:

みんなのおかげでこの問題を解決できました。宣言した代わりに、ジェネリック型を TabbedWorkspaceView に渡す必要がありました。したがって、新しいバージョンは次のとおりです。

 public partial class TabbedWorkspaceView<TTabbedWorkItemViewFrame, TWorkItemMainView>
        : KryptonNavigator,
        IMdiWorkspaceView<TTabbedWorkItemViewFrame, TWorkItemMainView, TWorkItemMainView>
        where TTabbedWorkItemViewFrame : TabbedWorkItemViewFrame<TWorkItemMainView>
        where TWorkItemMainView : AbstractWorkItemView

その後:

 public class TabbedWorkspaceController<TWorkItemController, TTabbedWorkspaceView, TTabbedWorkItemViewFrame, TWorkItemMainView>
        : MdiWorkspaceController<TWorkItemController, TTabbedWorkspaceView, TTabbedWorkItemViewFrame, TWorkItemMainView>
        where TWorkItemController : ViewableWorkItemController
        where TTabbedWorkspaceView : TabbedWorkspaceView<TTabbedWorkItemViewFrame, TWorkItemMainView>
        where TTabbedWorkItemViewFrame : TabbedWorkItemViewFrame<TWorkItemMainView>
        where TWorkItemMainView : AbstractWorkItemView

次に、アプリケーション レベルで次のことができます。

public class TappWorkspaceController
    : TabbedWorkspaceController<TappWorkItemController, TappWorkspaceView, TappWorkItemViewFrame, TappWorkItemView>
4

3 に答える 3

1

別の定義でジェネリック型を使用できます。これは簡単な例です:

class Program
{  
    public interface IBadFoo
    {
        void DoSomethingUnusual();
    }

    public interface IFoo
    { 
        void DoSomething();
    }

    public class Foo : IFoo
    {
        public void DoSomething()
        {           
        }
    }

    public abstract class SomeGenericBase<IFooClass>
        where IFooClass : IFoo
        //where IFooClass : IBadFoo
    {
        public abstract void DoSomethingElse();
    }

    public class SomeGeneric<FooClass> : SomeGenericBase<FooClass>
        where FooClass : Foo, new()
    {
        public override void DoSomethingElse()
       {
           FooClass fc = new FooClass();
           fc.DoSomething();
       }
   }

   public static void Main()
   {
       SomeGeneric<Foo> someGen = new SomeGeneric<Foo>();
       someGen.DoSomethingElse();
   }
}

コメントwhere IFooClass : IFooしてコメント//where IFooClass : IBadFooを外すと、Foo から IBadFoo への変換がないため、同様のエラーが発生することに注意してください。したがって、継承構造とパラメーターのどこかに、コンパイラーのパスまたはパスの不一致はないと思います。ソースが見つかるまで、パラメータを削除して問題領域を単純化することをお勧めします。

于 2013-09-11T02:35:53.517 に答える
1

このコードは非常に複雑で、それを解くのにしばらく時間がかかりました (そして、それが何を意味するのかまだ理解できません)。

問題は、とが直接関連していることを必要とすることだと思いますが、それを保証するものではありません。MdiWorkspaceControllerTMdiWorkspaceViewTWorkItemViewFrame

これを修正するには、IMdiWorkspaceViewインターフェイスを次のように変更します。

public interface IMdiWorkspaceView<TWorkItemViewFrame, T2, T3>

に:

public interface IMdiWorkspaceView<in TWorkItemViewFrame, T2, T3>

in基本的に の要件を緩和しTWorkItemViewFrame、コードをコンパイルします。

の定義が でIMdiWorkspaceViewコンパイルできないin場合は、記述されたコードがタイプ セーフではないことを意味します。

于 2013-09-11T02:47:17.867 に答える
1

この投稿は関連があると思います:

制約は署名の一部ではありません

あなたの質問は私の脳を傷つけますが、私はこれが起こっていると信じています:

  • この情報は、署名の一部ではない制約を介してのみ提供されるため、コンパイラは がTTabbedWorkspaceViewであることを「認識」しません。TabbedWorkspaceView

  • TTabbedWorkspaceViewの継承を介してMdiWorkspaceControllerasに渡されます。TMdiWorkspaceViewTabbedWorkspaceController

  • MdiWorkspaceControllerの制約検証はTMdiWorkspaceView、 であることが「知られていない」ものとして指定されたため、に対して失敗しますIMdiWorkspaceView

解決策: CA1005

于 2013-09-11T01:50:19.440 に答える