7

私は必要なものに対してエレガントでない解決策を持っていますが、それを置き換えるためのエレガントな解決策を探しています。

次のコードはコンパイルされませんが、私がやりたいことを表しています。

interface IWebService
{
}

abstract class BaseClient<T>
{
}

class SpecializedClient : BaseClient<IWebService>
{
}

class ClientHelper<T> where T : BaseClient<*>
{
}

ここで、Tinは、渡されたテンプレートタイプに関係なくClientHelper<T>拡張するクラスです。BaseClient

私が見つけたエレガントでない解決策は次のとおりです。

class ClientHelper<T, U> where T : BaseClient<U> {}

これがエレガントでなくなる理由は、私のプロジェクトが次のようなクラスになってしまうためです。

class MyClass<A, B, C, D, E, F, G> where A  : MyBaseClass<B, C, D, E, F, G>

単一の型をとる基本クラスに至るまで。これは単にジェネリッククラスの複雑な継承ツリーを持つためのコストですか、それともテンプレート型の型制限を保持しながらこれを行うためのより簡単な方法がありますか?

4

2 に答える 2

5

BaseClientのパブリックインターフェイスがジェネリック型パラメーターを何らかの方法で公開している場合は、「不正な」ソリューションが適切です。

したがって、あなたが定義したとおりでBaseClientないと仮定します。

abstract class BaseClient<T>
{
   //Something about T here
}

その場合、TはのパブリックインターフェイスコントラクトのBaseClient一部であり、したがってのパブリックインターフェイスコントラクトの一部です(ここでも、 ClientHelperのインターフェイスを介して公開されているとClientHelper仮定します)。BaseClient<U>

一方、実際には、例に示されているとおりであると仮定しましょう。

abstract class BaseClient<T>
{
   //Nothing about T here
}

その場合、次のことができます。

interface IBaseClient
{
   //Nothing about T here
}

abstract class BaseClient<T> : IBaseClient
{ 
    // Whatever you like here
}

そして次のようにClientHelperなります:

class ClientHelper<T> where T : IBaseClient
{
}
于 2012-04-04T03:42:28.817 に答える
0

1つのオプションは次のようです:

interface IWebService
{
}

interface IClient<out T>
{
}

abstract class BaseClient<T> : IClient<T>
{
}

class SpecializedClient : BaseClient<IWebService>
{
}

class ClientHelper<T> where T : IClient<object>
{
}

BaseClientただし、それはあなたが戻っTてそれを決して受け入れない場合にのみ機能します。

于 2012-04-04T04:32:39.033 に答える