2016-09-16 5 views
1

Genericsを使用する場所で複数のインターフェイスを実装しました。以下は私のコードです汎用の複数のインターフェイス

public class createGenericClass<T> where T : IWebService,IVoiceService 
{ 
    public void CallDoSomeThing(T t, int x, int y) 
    { 
     t.DoSomeThing(x, y); 
    } 

    public void CallDoSomeThingElse(T t, int a, float b) 
    { 
     t.DoSomeThingElse(a, b); 
    } 

} 

public interface IWebService 
{ 
    void DoSomeThing(int x, int y);   
} 

public interface IVoiceService 
{ 
    void DoSomeThingElse(int a, float b); 
} 

public class Web_Service : IWebService 
{ 
    public void DoSomeThing(int x, int y) 
    { }  
}  

public class Voice_Service : IVoiceService 
{ 
    public void DoSomeThingElse(int a, float b) 
    { } 
} 

ここで、メインメソッドのメインクラスのインスタンスを作成することはできません。私は試していましたが、できませんでした。

class Program 
{ 
    static void Main(string[] args) 
    { 
     createGenericClass<IWebService> obj = new createGenericClass<IWebService>(); 
    } 
} 

お勧めします。

+0

"できません "、どうしたらいいのですか?コンパイラに不満がある場合は、実際のコンパイラエラーを教えてください。 –

答えて

3

解決策1

この問題は、共通のインターフェイスを使用して解決できます。そのインターフェイスはヘルパー(createGenericClass)クラスのインスタンスによって使用され、渡す他のインターフェイスでも使用されます。それをIBaseServiceとしましょう。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var obj = new createGenericClass<IBaseService>(); 
     obj.CallDoSomeThing(new Web_Service(), 1, 2); // works well 
     obj.CallDoSomeThingElse(new Voice_Service(), 3, 4); // works well 
    } 
} 

注:

public class createGenericClass<T> 
    where T : IBaseService // telling T can be only IBaseService and inherited stuff. 
{ 
    public void CallDoSomeThing(T t, int x, int y) 
    { 
     (t as IWebService)?.DoSomeThing(x, y); // casting and validating 
    } 

    public void CallDoSomeThingElse(T t, int a, float b) 
    { 
     (t as IVoiceService)?.DoSomeThingElse(a, b); // casting and validating 
    } 
} 

public interface IBaseService{} // only gives a common parent to other interfaces. Common properties, methods can be included here. 

public interface IWebService : IBaseService // inheriting the common interface 
{ 
    void DoSomeThing(int x, int y);   
} 

public interface IVoiceService : IBaseService // inheriting the common interface 
{ 
    void DoSomeThingElse(int a, float b); 
} 

だから、あなたはこの方法あなたのヘルパークラスをインスタンス化でき、また、そのような作りなど、あなたのヘルパークラスの使用方法を簡素化するために使用できるいくつかのステップがあり、ヘルパークラス静的(多分シングルトン)ジェネリックスを使用せずジェネリックメソッドのみをメソッドで使用します。このようにして、クラスをインスタンス化する必要はありません。しかし
、これらは変更のパフォーマンスと使いやすさは、あなたがなどで作業しているデータや他のマネージャクラスに、利用状況の文脈に、あなたの目標に依存する「簡素化」..


ソリューション2 - (あなたの仕事はジェネリックスなしで解決できる)

あなたは受け取ったインスタンスをキャストしたくないと言った。これらのインスタンスで異なるメソッドを呼び出す場合は、ヘルパークラスのさまざまなメソッドを呼び出すことでそれらを呼び出すことになります。この場合、Genericsは本当に必要ありません。

これは、IBaseServiceやGenericsを使わずに仕事をします。

public class createGenericClass 
{ 
    public void CallDoSomeThing(IWebService t, int x, int y) 
    { 
     t.DoSomeThing(x, y); 
    } 

    public void CallDoSomeThingElse(IVoiceService t, int a, float b) 
    { 
     t.DoSomeThingElse(a, b); 
    } 
} 

ソリューション3から(ここで推奨されていない二重ジェネリックものは、)

あなたはそれを求めてきましたので:

public class createGenericClass<T, V> 
    where T: IWebService 
    where V: IVoiceService 
{ 
    public void CallDoSomeThing(T t, int x, int y) 
    { 
     t.DoSomeThing(x, y); 
    } 

    public void CallDoSomeThingElse(V t, int a, float b) 
    { 
     t.DoSomeThingElse(a, b); 
    } 
} 

用途:

static void Main(string[] args) 
{ 
    var obj = new createGenericClass<IWebService, IVoiceService>(); 
    obj.CallDoSomeThing(new Web_Service(), 1, 2); 
    obj.CallDoSomeThingElse(new Voice_Service(), 3, 4); 
} 
+0

返信いただきありがとうございます。あなたの場合、あなたはキャスティングをしていて、パフォーマンスには向いていません。このクラスをインスタンス化する方法を教えてください "public class createGenericClass ここで、T1:IWebService、IVoiceService" – KiddoDeveloper

+0

私は2つ以上のインターフェースを実装する必要がある場合、どのようにインスタンスを作成しますか? – KiddoDeveloper

+0

キャスティングなしで動作する私の答えを更新しました。あなたの目的に合っておらず、タイプをキャストしたくないのであれば、IBaseServiceのように、おそらくインターフェイスで遊ぶ必要があります。メソッドをグループ化する必要がありますので、1つのインターフェースでそれらを呼び出すことができます。 – KAI

4

デザインタイプTは、IWebServiceIVoiceServiceの両方である必要があります。 objを初期化する方法は、IWebServiceのみを使用していますが、これはIVoiceServiceではありません。

それを解決する1つの方法は、複数の一般的なクラスにあなたのジェネリッククラスを分割することです - IVoiceServiceためIWebService用と別:

public class createGenericClassWeb<T> where T : IWebService 
{ 
    public void CallDoSomeThing(T t, int x, int y) 
    { 
     t.DoSomeThing(x, y); 
    } 
} 

public class createGenericClassVoice<T> where T : IVoiceService 
{ 
    public void CallDoSomeThingElse(T t, int a, float b) 
    { 
     t.DoSomeThingElse(a, b); 
    } 
} 

その後、あなたは、このようにそれらを使用することができます。

createGenericClassWeb<IWebService> objWeb = new createGenericClassWeb<IWebService>(); 
createGenericClassVoice<IVoiceService> objVoice = new createGenericClassVoice<IVoiceService>(); 

この場合、なぜジェネリックが必要なのかはっきりしませんが、次のような単純なクラスを使用することができます:

public class createNonGenericClassWeb 
{ 
    public void CallDoSomeThingElse(IWebService t, int a, float b) 
    { 
     t.DoSomeThing(a, b); 
    } 
} 
+1

しかし、私は2つのインターフェイス "public class createGenericClass ここでT1:IWebService、IVoiceService" – KiddoDeveloper

0

cannあなたのタイプ「IWebServiceは」

createGenericClass<IWebService> obj = new createGenericClass<IWebService>(); 

createGenericClassは「T」と呼ばれるタイプのパラメータを取り制約「IWebService、IVoiceService」に一致しないため、OTは、あなたの構文を使用して新しいインスタンスを作成します。 Tの制約は、IWebServiceとIVoiceServiceを実装する必要があります。つまり、Tパラメータに指定する型は、両方のインタフェースを実装する型でなければなりません。例えば

:実装IWebServiceとIVoiceService上記の両方

public class Voice_And_Web_Service : IWebService,IVoiceService 
{ 
    public void DoSomeThing(int x, int y) 
    { }  

    public void DoSomeThingElse(int a, float b) 
    { } 
} 

クラスなので、制約を渡し、インスタンスを作成することができます。私は他の回答が優れている、あなたが直面している問題の多くをカバーし、私はあなたが「のインスタンスを作成することはできないことについて尋ね正確に質問をカバー1を見ていないと信じて

createGenericClass<Voice_And_Web_Service> obj = new createGenericClass<Voice_And_Web_Service>(); 

メインクラス "

関連する問題