2017-07-10 12 views
2

私は汎用インターフェースIFace<T, U>を持っていると言います。 TUはいくつかの追加の方法で制約を受けることがありますが、これは問題には関係しないと思います。汎用クラスと簡約制約?

私は次のように定義して新しいジェネリッククラスGenClassを作成したいと思います:

class GenClass<T> where T: IFace

すなわち、私は、GenClassが汎用タイプを指定せずにIFaceの実装を処理する必要があることをコンパイラに伝えたいと思います。

TUの一般的なパラメータを指定する必要がありますか?

IFaceIFace<>またはIFace<,>と書いてみましたが、コンパイラは常にフィットしました。だから私はこれができないと思っています。それでも、おそらく私はこれについて間違った方法をとっていますか?

+0

'IFace 'インターフェイスは、 'T'と' U'で指定されたクラスを持たないと意味をなさない。どのような行動を望んでいますか?つまり、書いておきたいコードの例を挙げることができますか?ジェネリックスが間違っていたり、間違った方法で問題を解決しようとしているように間違っているようです... – Chris

+0

@Chris現実には、2つの異なる実装を登録するサービスロケータのヘルパーメソッドを作成しようとしています。インターフェース(そしてそれらの実装のうちの1つはもう1つの制約よりも少し制約があります)。問題は、基本インターフェースにはすでに2つの汎用パラメータがあるため、ヘルパークラスにはコンパイルするための5つの汎用パラメータが必要であるということです(これはうまくいきますが)。そういうわけで、物事を単純化する方法がないのだろうかと思っていました。 – Shaamaan

+0

ああ。あなたがどこから来ているのか、おおよそわかります。単純化できるかどうかを尋ねたコードで別の質問をするべきかどうか疑問に思っています。 codreview.stackexchange.comに置くのが最善であるかどうかわからない(免責事項:私はそこに遊んでいるわけではないので、トピックにあるものの漠然とした考えがあるので、チェックしてください)コードが動作してから、より読みやすくすることができれば。 – Chris

答えて

7

が、このことは可能ですか、私はTとU汎用パラメータを指定する必要がありますか?

あなたはそれらが必要です、私は恐れています。あなた続い

public interface IFace 
{ 
    // Include anything that doesn't need the type parameters here 
} 

public interface IFace<T1, T2> : IFace 
{ 
    // Include anything that needs the type parameters here 
} 

:それは多くの場合、最も簡単な方法です - あなたは一般的なものから派生非ジェネリックIFaceインターフェイスを作成することはできませんと仮定しています

class GenClass<T, TX, TY> where T : IFace<TX, TY> 

を持っている必要があります

class GenClass<T> where T : IFace 

これは非ジェネリックインターフェースが実際に存在するようになったためです。

0

次の操作を行うことができます。

class GenClass<T, TT, TU> where T: IFace<TT, TU> 

GenClassを初期化するときに、3つのパラメータをすべて定義できます。

class MyFace<T, U> : IFace<T, U> 

var instance = new GenClass<MyFace<string, int>>(); 

それとも


あなたがたとえば、あなたもこれを行うことができますについての2つのプロパティを知っている以外の一般的な基本型を提供する場合

class MyFace : IFace<string, int> 

var instance = new GenClass<MyFace>(); 

interface IFace<T, U> 
{ 
    T ValueOne { get; set; } 
    U ValueTwo { get; set; } 
} 

abstract class FaceBase : IFace<object, object> 
{ 
    public object ValueOne { get; set; } 
    public object ValueTwo { get; set; } 

    protected FaceBase(object valueOne, object valueTwo) 
    { 
     ValueOne = valueOne; 
     ValueTwo = valueTwo; 
    } 
} 

class GenClass<T> where T : FaceBase 
{ 
    private T Value { get; set; } 

    public GenClass() 
    { 
     // do something with Value.ValueOne or Value.ValueTwo 
    } 
} 

FaceBaseの実装は、次のようになります。

class MyFace : FaceBase, IFace<string, int> 
{ 
    public new string ValueOne 
    { 
     get => base.ValueOne as string; 
     set => base.ValueOne = value; 
    } 

    public new int ValueTwo 
    { 
     get => (int) base.ValueTwo; 
     set => base.ValueTwo = value; 
    } 

    public MyFace(string valueOne, int valueTwo) 
     : base(valueOne, valueTwo) 
    { } 
} 
+0

これは私が意図したことですか "、あるいは、' T'と 'U'ジェネリックパラメータを指定する必要がありますか?クラス定義を単純化しようとしています。すべての用途で 'T'と' U'パラメータを指定することは、私の場合は実際には役に立たないからです。 :/ – Shaamaan

+0

また、 'T'や' U'といった特定の型を持つ特定の 'IFace'実装を作成することもできません。 – Shaamaan

+0

@Shaamaanもう1つの可能性を追加しましたが、これはあなたのタイプ(私の投稿の例ではプロパティとして)にアクセスできるようにします。 – NtFreX

1

いいえ、できません。そう、あなたはGenClassTFaceUFaceに興味がないようにあなたの質問に基づいて

class GenClass<T, TFace, UFace> where T: IFace<TFace, UFace> 

しかし、それはそう:そうでなければ、あなたに立ち往生

interface IFace { } 
interface IFace<T, U>: IFace { } 
class GenClass<T> where T: IFace 

:あなたが得ることができる最も近い次のようですジェネリックでないインターフェースはすべきです。

関連する問題