2016-06-20 1 views
0

汎用クラスの現在の構造が与えられている場合。私が欲しいものタイプは、汎用クラスのパラメータとして使用するために変換可能でなければなりません

public abstract class Foo<TFoo, TBar> 
    where TFoo : Foo<TFoo, TBar> 
    where TBar : Bar<TFoo, TBar> 
{ 
} 

public abstract class Foo<TFoo> : Foo<TFoo, BarImpl> 
    where TFoo : Foo<TFoo> 
{ 
} 

public class FooImpl : Foo<FooImpl> 
{ 
} 

public abstract class Bar<TFoo, TBar> 
    where TFoo : Foo<TFoo, TBar> 
    where TBar : Bar<TFoo, TBar> 
{ 
} 

public abstract class Bar<TFoo> : Bar<TFoo, BarImpl> 
    where TFoo : Foo<TFoo> 
{ 
} 

public class BarImpl : Bar<FooImpl> 
{ 
} 

Foo<TFoo>の各実装にデフォルトBarを設定することです。 コード内の他の部分でTBarのインスタンスが作成されます。の場合は失敗し、abstractクラスです。

しかし、次のエラーがスローされ、私は何ができるのか、これがまったく可能なのか分かりません。

型「BarImplは」パラメータとしてそれを使用するために「バー」に変換可能でなければならない「TBar」ジェネリッククラスに「foo」で

私はすでにBarImplBar<FooImpl, BarImpl>から派生させてみましたそれは効果がなかった。

タイプBar<TFoo>のオブジェクトがintantiatedされるまで(それはabtractだのため)

public abstract class Foo<TFoo> : Foo<TFoo, Bar<TFoo>> 
    where TFoo : Foo<TFoo> 
{ 
} 

public abstract class Bar<TFoo> : Bar<TFoo, Bar<TFoo>> 
    where TFoo : Foo<TFoo> 
{ 
} 

にそれを変更すると動作します。

+3

おそらく、あまりにも多くのレベルのジェネリックと迂回があります。私は自分の頭を回転させて、どんなタイプが継承しているか、実装しているか、または制約に基づいているか、制約に従っているかを追求します。この例を簡略化することはできますか? –

+0

Fooは独自のBarインスタンスを作成してはいけませんが、FooImplから継承された(コンストラクタ)か継承されている必要がありますか? – Terence

+0

@ LasseV.Karlsen私はこのことについて数日から頭が回転しているので、これを単純化してうれしいです。どんなアイデアでも大歓迎です。私の質問が私がここで達成しようとしていることを明確にするかどうか分かりません... – KingKerosin

答えて

1

私はあなたの一般的な再帰ループを終了する必要が推測:

一般インタフェース:

public interface IFoo 
{ 
} 

public interface IBar 
{ 
} 

したい相続の種類に応じて:

public interface IFoo<TFoo> : IFoo 
    where TFoo : IFoo 
{ 
} 

public interface IBar<TBar> : IBar 
    where TBar : IBar 
{ 
} 

public interface IFoo<TFoo, TBar> : IFoo<IFoo> 
    where TFoo : IFoo 
    where TBar : IBar 
{ 
} 

public interface IBar<TFoo, TBar> : IBar<IBar> 
    where TFoo : IFoo 
    where TBar : IBar 
{ 
} 

または:

public interface IFoo<TFoo, TBar> : IFoo 
    where TFoo : IFoo 
    where TBar : IBar 
{ 
} 

public interface IBar<TFoo, TBar> : IBar 
    where TFoo : IFoo 
    where TBar : IBar 
{ 
} 

public interface IFoo<TFoo> : IFoo<TFoo, IBar> 
    where TFoo : IFoo 
{ 
} 

public interface IBar<TBar> : IBar<IFoo, TBar> 
    where TBar : IBar 
{ 
} 

抄録クラス:

public abstract class AFoo<TFoo, TBar> : IFoo<TFoo, TBar> 
    where TFoo : IFoo 
    where TBar : IBar 
{ 
} 

public abstract class ABar<TFoo, TBar> : IBar<TFoo, TBar> 
    where TFoo : IFoo 
    where TBar : IBar 
{ 
} 

実装クラス:

public class Foo<TFoo, TBar> : AFoo<TFoo, TBar> 
    where TFoo : IFoo 
    where TBar : IBar 
{ 
} 

public class Bar<TFoo, TBar> : ABar<TFoo, TBar> 
    where TFoo : IFoo 
    where TBar : IBar 
{ 
} 


public class Foo<TFoo> : AFoo<TFoo, IBar> 
    where TFoo : IFoo 
{ 
} 

public class Bar<TBar> : ABar<IFoo, TBar> 
    where TBar : IBar 
{ 
} 

public class Foo : AFoo<IFoo, IBar> 
{ 
} 

public class Bar : ABar<IFoo, IBar> 
{ 
} 

使用法:

var test = new Foo<IFoo<IFoo<IFoo, IBar<IFoo, IBar>>, IBar>, IBar>(); 

私はまだあなたがより良い説明をして、ここで達成しようとしているのかを理解していませんよりよい解決策にすべきである。

関連する問題