简体   繁体   English

通用的多个接口

[英]Multiple Interfaces in Generic

I have implemented multiple interfaces in where using Generics. 我在使用泛型的地方实现了多个接口。 Below is my code 下面是我的代码

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

Now, I am not able to create a instance of the main class in Main method. 现在,我无法在Main方法中创建主类的实例。 I was trying but m not able to do. 我正在尝试,但是我做不到。

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

Please suggest. 请提出建议。

With your design type T needs to be both IWebService and IVoiceService . 对于您的设计类型, T必须同时是IWebServiceIVoiceService The way you try to initialize obj , you are only using IWebService , which is not IVoiceService . 尝试初始化obj的方式仅使用IWebService ,而不是IVoiceService

One way to solve it is to split your generic class into multiple generic classes - one for IWebService and another for 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);
    }
}

Then you can use them like this: 然后,您可以像这样使用它们:

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

Although in this case it is not clear why you need generics at all, you might use simple class like this: 尽管在这种情况下根本不清楚为什么需要泛型,但是您可以使用像这样的简单类:

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

Solution 1 解决方案1

You can solve this problem by using a common interface. 您可以通过使用通用接口来解决此问题。 That interface will be used by your helper ( createGenericClass ) class instance, and will be used by your other interfaces which you would like to pass, as well. 该接口将由您的助手( createGenericClass )类实例使用,并且还将与您要传递的其他接口一起使用。 Let's call it IBaseService . 我们称之为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, you could instantiate your helper class this way: 因此,您可以通过以下方式实例化您的帮助器类:

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

Note: also, there are several steps which you could use to simplify the usage of you helper class, such as making the helper class static (maybe Singleton) without Generics and use generics only on methods only. 注意:另外,您可以使用几个步骤来简化辅助类的使用,例如,使辅助类变为静态(可能是Singleton)而不使用泛型,而仅对方法使用泛型。 This way you wouldn't need to instantiate the class. 这样,您就无需实例化该类。
However, these "simplifying" modifications' performance and usability would depend on your goals, on the context of usage, on the data and other manager classes you are working with etc.. 但是,这些“简化”修改的性能和可用性将取决于您的目标,使用环境,数据以及您正在使用的其他管理器类等。


Solution 2 - (Your task could be solved without Generics) 解决方案2- (无需泛型即可解决您的任务)

You said that you don't want to cast the received instances. 您说过您不想投射接收到的实例。 Since you would like to call different methods on those instances, you are calling those by calling different methods on you helper class. 由于您想在这些实例上调用不同的方法,因此通过在助手类上调用不同的方法来调用这些方法。 In this case, you don't really need Generics. 在这种情况下,您实际上不需要泛型。

This would do the job, without using IBaseService or even Generics. 这样就可以完成工作,而无需使用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);
    }
}

Solution 3 - (The double-Generic stuff, which is NOT recommended here) 解决方案3- (双通用的东西,这里不推荐)

Since you've asked for it: 由于您已经要求:

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

Usage: 用法:

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

You cannot create a new instance using your syntax because your type "IWebService" does not match the constraints "IWebService,IVoiceService" 您无法使用语法创建新实例,因为类型“ IWebService”与约束“ IWebService,IVoiceService”不匹配

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

createGenericClass takes a type parameter called "T". createGenericClass采用名为“ T”的类型参数。 The constraints on T require that it implement IWebService and IVoiceService. 对T的约束要求它实现IWebService和IVoiceService。 That means that the type you supply for the T parameter must be a type that implements both interfaces. 这意味着您为T参数提供的类型必须是实现两个接口的类型。

For example: 例如:

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

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

The class above implements both IWebService and IVoiceService, so it passes the constraints and you will be able to create an instance. 上面的类同时实现了IWebService和IVoiceService,因此它传递了约束,您将能够创建一个实例。

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

I believe the other answers are excellent and cover a lot of the issues you are facing, but I did not see one that covered precisely the question you asked about being "not able to create an instance of the main class" 我相信其他答案很好,可以解决您面临的许多问题,但是我没有看到一个答案能够准确地解决您所提出的“无法创建主类实例”的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM