C# 使用从内部子对象确定的类型实现泛型列表getter?
对于上下文,我正在为Navision web服务创建一个包装器类 其结构如下:C# 使用从内部子对象确定的类型实现泛型列表getter?,c#,generics,C#,Generics,对于上下文,我正在为Navision web服务创建一个包装器类 其结构如下: class JobList_Service : SoapHttpClientProtocol { public Job[] ReadMultiple() { ... } } 我想做如下事情: var jobWS = new NavService<JobList_Service>(); jobWS.GetAll<Job>
class JobList_Service : SoapHttpClientProtocol
{
public Job[] ReadMultiple()
{
...
}
}
我想做如下事情:
var jobWS = new NavService<JobList_Service>();
jobWS.GetAll<Job>();
var jobWS=new NavService();
jobWS.GetAll();
我正在与泛型作斗争,我不知何故需要声明第二个类型,因为它将JobList_服务作为一个类型,因此返回一个JobList_服务列表,这不是我想要的
以下是我目前的实施情况:
public class NavService<T> where T : SoapHttpClientProtocol, new()
{
private T serviceInstance {get; set;}
public NavService()
{
serviceInstance = new T();
ADSecurity.AuthenticateService_CurrentUser(serviceInstance);
}
public List<T> GetAll()
{
try
{
MethodInfo method = serviceInstance.GetType().GetMethod("ReadMultiple");
ParameterInfo[] paramTypes = method.GetParameters(); //We know that ReadMultiple takes three arguments, we will make that assumption here.
var filter = Activator.CreateInstance(paramTypes[0].ParameterType, 0);
object[] parameters = { filter, "", new Int32() };
var ret = (List<T>)/*Problem with this cast, obviously*/ method.Invoke(serviceInstance, parameters) ;
return ret;
} catch (Exception ex)
{
throw ex;
}
}
}
公共类导航服务,其中T:SoapHttpClientProtocol,new()
{
私有T服务实例{get;set;}
公共服务()
{
serviceInstance=newt();
ADSecurity.AuthenticateService\u CurrentUser(serviceInstance);
}
公共列表GetAll()
{
尝试
{
MethodInfo method=serviceInstance.GetType().GetMethod(“ReadMultiple”);
ParameterInfo[]paramTypes=method.GetParameters();//我们知道ReadMultiple接受三个参数,我们将在这里进行假设。
var filter=Activator.CreateInstance(paramTypes[0]。ParameterType,0);
object[]参数={filter,“,new Int32()};
var ret=(List)/*此强制转换存在问题,显然是*/method.Invoke(serviceInstance,parameters);
返回ret;
}捕获(例外情况除外)
{
掷骰子;
}
}
}
*编辑:如果有人能推荐一个更好的标题,请放心,我不知道正确的术语。您可以用两个类型参数来解决这个问题-一个用于服务类型,一个用于响应类型:
public class NavService<T, TResponse>
{
...
public List<TResponse> GetAll()
{
}
}
然后将其传递到NavService
构造函数:
public class NavService<T>
{
private IJobListService<T> _serviceInstance;
public NavService(IJobListService<T> serviceInstance)
{
_serviceInstance = serviceInstance;
/* authenticate the service outside of this scope (i.e. before
* it is passed to this ctor). This breaks encapsulation.
* ADSecurity.AuthenticateService_CurrentUser(serviceInstance); */
}
public List<T> GetAll() { }
}
公共类导航服务
{
私有IJobListService\u serviceInstance;
公共导航服务(IJobListService服务实例)
{
_serviceInstance=serviceInstance;
/*在此范围之外对服务进行身份验证(即在
*它被传递给这个ctor)。这破坏了封装。
*ADSecurity.AuthenticateService\u CurrentUser(serviceInstance)*/
}
公共列表GetAll(){}
}
这加强了更好的封装,还应该防止您不得不进行所有不愉快的反射(您必须自己在这方面做一些额外的工作,因为我不知道具体类型的所有细节),并允许您只调用方法
编辑:因为您的评论指出您的服务是生成的,所以我将把您的每个服务包装在一个适配器中,您可以将接口应用到该适配器:
public class JobListService : IListService<Job>
{
// Your generated service
private readonly JobList_Service _service;
... // set up service in ctor or wherever
public Job[] ReadMultiple()
{
return _service.ReadMultiple();
}
}
公共类JobListService:IListService
{
//您生成的服务
私有只读作业列表服务;
…//在ctor或任何位置设置服务
公共作业[]ReadMultiple()
{
return _service.ReadMultiple();
}
}
Hmm,但是JobList\u服务是自动生成的代码,我不是需要在每次生成时将接口添加到它的声明中吗?我没有意识到这一点-在这种情况下,我不直接应用接口,而是编写一些小适配器来镜像方法签名,但实现接口,看起来我需要做一些关于如何做到这一点的研究,对泛型来说有点新。顺便说一下,接口部分是惊人的,非常干净的实现@大卫扩展了我的回答,以证明我的最后一句话:)
public class JobListService : IListService<Job>
{
// Your generated service
private readonly JobList_Service _service;
... // set up service in ctor or wherever
public Job[] ReadMultiple()
{
return _service.ReadMultiple();
}
}