2016-09-16 35 views
1

我在使用泛型的地方實現了多個接口。以下是我的代碼泛型中的多個接口

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) 
    { } 
} 

現在,我無法在Main方法中創建主類的實例。我試圖但不能做到。

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

請建議。

+0

」不行「,你能告訴我們會發生什麼嗎?如果編譯器抱怨,你需要告訴我們實際的編譯器錯誤。 –

回答

3

解決方案1 ​​

您可以通過使用通用接口來解決此問題。該接口將由您的幫助程序(createGenericClass)類實例使用,並且您的其他接口也將使用您希望傳遞的接口。我們稱之爲IBaseService

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); 
} 

所以,你可以實例化助手類是這樣的:

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 
    } 
} 

注:也有幾個步驟,你可以用它來簡化你的使用輔助類,如做沒有泛型的輔助類static(也許是Singleton),僅在方法上使用泛型。這樣你就不需要實例化類。
然而,這些「簡化」修改性能和可用性將取決於你的目標,在使用的情況下,對數據和其他管理類您正在使用等工作..


解決方案2 - (你的任務可以在沒有泛型的情況下解決)

你說你不想轉換收到的實例。既然你想在這些實例上調用不同的方法,你可以通過在你的helper類上調用不同的方法來調用它們。在這種情況下,你並不需要泛型。

這將完成這項工作,而不使用IBaseService甚至泛型。

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

謝謝你的答覆。在你的情況下,你正在進行鑄造,這對性能不利。請告訴我如何實例化這個類「公共類createGenericClass 其中T1:IWebService,IVoiceService」 – KiddoDeveloper

+0

如果我有一個條件,我需要實現兩個或多個接口,我將如何創建一個實例? – KiddoDeveloper

+0

我已經更新了我的答案,可以在不投射的情況下工作。如果它不適合你的目的,並且你不想投入類型,那麼你可能不得不使用接口 - 就像我對IBaseService所做的那樣。您必須對方法進行分組,因此您可以在ONE界面上對其進行調用。 – KAI

4

隨着你的設計類型T需要是IWebServiceIVoiceService。您嘗試初始化obj的方式,您只使用IWebService,而不是IVoiceService

一個解決這個問題的方法是將通用類分割成多個泛型類 - 一個用於IWebService,另一個用於IVoiceService

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

好的。但有沒有什麼辦法可以調用單個實例/對象,我已經實現了兩個接口「公共類createGenericClass 其中T1:IWebService,IVoiceService」 – KiddoDeveloper

0

你cann OT使用語法創建一個新的實例,因爲你喜歡的類型「IWebService」不匹配

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

createGenericClass採取所謂的「T」類型參數的約束「IWebService,IVoiceService」。 T上的約束要求它實現IWebService和IVoiceService。這意味着您爲T參數提供的類型必須是實現這兩個接口的類型。

例如:

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

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

類以上的同時實現了IWebService和IVoiceService,所以它傳遞的約束,你將能夠創建一個實例。

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

我相信其他的答案是優秀的,涵蓋了很多你所面臨的問題,但我沒有看到一個涵蓋正是你問是「不能創建的實例的問題主類「