通用中的多个接口

时间:2016-09-16 05:25:05

标签: c# generics interface

我在使用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)
    { }
}

现在,我无法在Main方法中创建主类的实例。我正在尝试,但我无法做到。

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

请建议。

3 个答案:

答案 0 :(得分: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 :(得分: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
    }
}

注意:此外,还有几个步骤可用于简化辅助类的使用,例如使辅助类静态(可能是Singleton)而不使用泛型,并仅在方法上使用泛型。这样您就不需要实例化该类 然而,这些&#34;简化&#34;修改&#39;性能和可用性取决于您的目标,使用环境,您正在使用的数据和其他管理器类等。

解决方案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);
}

答案 2 :(得分:0)

您无法使用语法创建新实例,因为您的类型“IWebService”与约束“IWebService,IVoiceService”不匹配

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

createGenericClass采用名为“T”的类型参数。对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>();

我相信其他答案都非常出色,涵盖了你所面临的很多问题,但我没有看到一个问题,你提到的问题是“无法创建主类的实例” “