2016-09-16 1 views
1

Ich habe mehrere Schnittstellen in wo Generics implementiert. Unten ist mein CodeMehrere Schnittstellen in Generic

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

Jetzt kann ich keine Instanz der Hauptklasse in Main-Methode erstellen. Ich habe versucht, aber ich bin nicht in der Lage zu tun.

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

Bitte vorschlagen.

+0

" nicht fähig ", können Sie uns sagen, was passiert? Wenn der Compiler sich beschwert, müssen Sie uns den tatsächlichen Compilerfehler mitteilen. –

Antwort

3

Lösung 1

Sie dieses Problem durch die Verwendung einer gemeinsamen Schnittstelle lösen können. Diese Schnittstelle wird von Ihrer Klasseninstanz helper (createGenericClass) verwendet und von Ihren anderen Schnittstellen verwendet, die Sie auch übergeben möchten. Nennen wir es 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); 
} 

So konnten Sie Ihre Hilfsklasse auf diese Weise instanziiert:

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

Hinweis: auch gibt es mehrere Schritte, die Sie die Verwendung von Ihnen Hilfsklasse, wie zum Beispiel die Nutzung könnte zu vereinfachen die Helper-Klasse static (vielleicht Singleton) ohne Generics und Generics nur für Methoden verwenden. Auf diese Weise müssten Sie die Klasse nicht instanziieren.
jedoch diese „Vereinfachung“ Modifikationen Leistung und Benutzerfreundlichkeit auf Ihre Ziele, auf die Anwendungsbedingungen abhängen würde, auf die Daten und andere Manager-Klassen Sie mit etc arbeiten ..


Lösung 2 - (Ihre Aufgabe könnte ohne Generics gelöst werden)

Sie sagten, dass Sie nicht die empfangenen Instanzen werfen wollen. Da Sie für diese Instanzen unterschiedliche Methoden aufrufen möchten, rufen Sie diese auf, indem Sie verschiedene Methoden für Ihre Hilfsklasse aufrufen. In diesem Fall brauchen Sie Generics nicht wirklich.

Dies würde die Arbeit tun, ohne IBaseService oder sogar Generics zu verwenden.

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

Lösung 3-(Die Doppelallgemein Sachen, die hier nicht empfohlen)

Da Sie haben es heraufbeschworen:

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

Verbrauch:

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

Vielen Dank für die Antwort. In deinem Fall machst du Casting und das ist nicht gut für die Leistung. Bitte sagen Sie mir, wie man diese Klasse instanziieren kann "public class createGenericClass wo T1: IWebService, IVoiceService" – KiddoDeveloper

+0

Wenn ich eine Bedingung habe, wo ich zwei oder mehr Schnittstellen implementieren muss, wie erstelle ich eine Instanz ?? – KiddoDeveloper

+0

Ich habe meine Antwort aktualisiert, die ohne Casting funktionieren würde. Wenn es für deine Zwecke nicht gut ist und du keine Typen gießen willst, dann wirst du wahrscheinlich mit Interfaces spielen müssen - wie ich es mit IBaseService gemacht habe. Sie müssen Methoden gruppieren, damit Sie sie auf der EINEN Schnittstelle aufrufen können. – KAI

4

Mit Ihrem Design-Typ muss T sowohl IWebService als auch IVoiceService sein. Wie Sie versuchen, obj zu initialisieren, verwenden Sie nur IWebService, die nicht IVoiceService ist.

Ein Weg, um es zu lösen ist Ihr generische Klasse in mehrere generische Klassen aufgeteilt - eine für IWebService und eine andere für 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); 
    } 
} 

Dann können Sie sie wie folgt verwenden:

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

Obwohl in diesem Fall nicht klar ist, warum Sie überhaupt Generika benötigen, können Sie eine einfache Klasse wie diese verwenden:

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

Okay. Aber gibt es eine Möglichkeit, eine einzelne Instanz/Objekt aufzurufen, wo ich zwei Schnittstelle implementiert habe "öffentliche Klasse createGenericClass wo T1: IWebService, IVoiceService" – KiddoDeveloper

0

Sie können ot eine neue Instanz mit Ihrer Syntax erstellt werden, weil Ihre Art „IWebService“ entspricht nicht den Einschränkungen „IWebService, IVoiceService“

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

createGenericClass einen Typparameter nimmt namens „T“. Die Einschränkungen für T erfordern, dass es IWebService und IVoiceService implementiert. Das bedeutet, dass der Typ, den Sie für den T-Parameter angeben, ein Typ sein muss, der beide Schnittstellen implementiert.

Zum Beispiel:

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

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

Die Klasse über Geräte sowohl IWebService und IVoiceService, so leitet sie die Einschränkungen und Sie werden in der Lage, eine Instanz zu erstellen.

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

Ich glaube, die anderen Antworten sind ausgezeichnet und decken Sie konfrontiert sind, viele der Probleme, aber ich sah man nicht, dass gerade die Frage bedeckt Sie sind „nicht in der Lage gebeten, eine Instanz der erstellen Hauptklasse "

Verwandte Themen