c# - 实现一个通用的List getter,其类型是从内部子对象确定的?
对于上下文,我正在为Navision Web服务创建一个包装类。
它们具有以下结构:
class JobList_Service : SoapHttpClientProtocol
{
public Job[] ReadMultiple()
{
...
}
}
我想做以下事情:
var jobWS = new NavService<JobList_Service>();
jobWS.GetAll<Job>();
我在使用泛型时遇到困难,我不得不声明第二种类型,因为它将JobList_Service作为一个类型,因此返回一个JobList_Service列表,这不是我想要的。
到目前为止,这是我的实施:
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;
}
}
}
*编辑:如果有人可以提出更好的标题,请随意,我不知道正确的术语。
最佳答案:
1 个答案:
答案 0 :(得分:1)
你可以用两个类型参数解决这个问题 - 一个用于服务类型,一个用于响应类型:
public class NavService<T, TResponse>
{
...
public List<TResponse> GetAll()
{
}
}
但是,说实话,看起来你的通用类型根本不应该与JobList_Service
有任何关系(因为你所做的一切都是实例化服务)而且您应该实现一个接口并将其用作NavService
的依赖项。
注意:我在此假设你有多个&#34;列表服务&#34;每个返回不同的类型。你没有在你的问题中提到这一点,但这是我能想到需要通用GetAll
方法的唯一原因。
首先制作通用&#34;列表服务&#34;您可以为不同的具体类型实现的接口:
public interface IListService<T>
{
T[] ReadMultiple();
}
public class JobList_Service : IListService<Job>, SoapHttpClientProtocol
{
public Job[] ReadMultiple()
{
...
}
}
然后将其传递给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() { }
}
这可以强化更好的封装,也可以防止你不必做所有那些令人不快的反思(你必须自己做一些额外的腿部工作,因为我不知道所有的细节具体类型)并允许您只是调用方法。
编辑:由于您的评论指出您的服务已生成,因此我将每个服务包装在您可以将接口应用于的适配器中:
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();
}
}
本文经用户投稿或网站收集转载,如有侵权请联系本站。