通用的多个接口
本文关键字:接口 | 更新日期: 2023-09-27 18:07:15
我使用泛型实现了多个接口。下面是我的代码
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>();
}
}
请建议。
方案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
}
}
注意:还有几个步骤可以用来简化helper类的使用,例如将helper类设置为静态(可能是Singleton),而不使用泛型,并且只在方法上使用泛型。这样就不需要实例化类了。
然而,这些"简化"修改的性能和可用性将取决于您的目标、使用上下文、数据和您正在使用的其他管理器类等。
解决方案2 - (您的任务不需要泛型也可以解决)
您说您不想强制转换接收到的实例。由于您希望在这些实例上调用不同的方法,因此您通过在助手类上调用不同的方法来调用这些实例。在这种情况下,实际上不需要泛型。
这将完成工作,不需要使用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);
}
您的设计类型T
需要同时是IWebService
和IVoiceService
。你尝试初始化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);
}
}
你不能用你的语法创建一个新的实例,因为你的类型"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>();
我相信其他的答案都很好,涵盖了你面临的很多问题,但我没有看到一个准确地涵盖了你问的"无法创建主类的实例"的问题