c# - 实现一个通用的List getter,其类型是从内部子对象确定的?

c# - 实现一个通用的List getter,其类型是从内部子对象确定的?,第1张

对于上下文,我正在为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();
    }
}        
本文经用户投稿或网站收集转载,如有侵权请联系本站。

发表评论

0条回复