【问题标题】:Wrapping several different types in a common generic class for common access?将几种不同类型包装在一个通用泛型类中以进行通用访问?
【发布时间】:2010-10-27 21:12:32
【问题描述】:

我有几个返回各种结果的 Web 服务。有些结果是字符串,有些是数组(从 WSDL 自动生成)。当我调用Web服务时,我想得到所有的各种结果(包括异常),然后通过一个通用的接口对它们进行操作,但是由于类型的不同,我无法让它工作。在下面的示例中,T 是我要存储的类型(例如 List 或 string),U 是服务返回的类型(例如 Report[] 或 string)。

    private class Result<T, U> : ICommon
    {
        public delegate U ResultProvider();

        public readonly string ElementName = null;
        public readonly T Value = null;
        public readonly Exception Exception = null;

        public Result(string ElementName, ResultProvider Provider)
        {
            this.ElementName = ElementName;
            try
            {
                this.Value = Provider();
            }
            catch (Exception e) {
                this.Exception = e;
            }
        }
    }

如果所有服务都返回 List,那么合并 U 和 T 并执行以下操作将是微不足道的:

    private class Result<T> : ICommon
    {
        public delegate T[] ResultProvider();

        public readonly string ElementName = null;
        public readonly List<T> Value = null;
        public readonly Exception Exception = null;

        public Result(string ElementName, ResultProvider Provider)
        {
            this.ElementName = ElementName;
            try
            {
                this.Value = new List<T>(Provider());
            }
            catch (Exception e) {
                this.Exception = e;
            }
        }
    }

但是当 web 方法返回非数组时,这将不起作用。所以现在我有Result&lt;T&gt;ResultResult&lt;string&gt; 的有效手动编码版本)

对这个设计有什么建议吗?我应该看看有什么更好的模式吗?

【问题讨论】:

  • 可能存在更好的模式,但是 a) 尝试 LINQ .ToArray() 或 b) 尝试 new[]{ mystring }

标签: c# oop generics


【解决方案1】:

我认为反射是你想要的。

您可以使用 typeof(U) 来获取 ResultProvder 的返回类型,然后很容易弄清楚返回类型是什么并进行相应的处理。你可以去执行 .IsArray 然后 .GetMethod 来访问返回类型的成员。

【讨论】:

    【解决方案2】:

    我不确定我是否完全理解您,但在您的第一个示例中,您能否创建一个构造函数的重载,该构造函数采用 Func&lt;U, T&gt;Us 转换为 Ts?因此,如果服务返回 Person[],您可以拥有

    public Result(string ElementName, ResultProvider Provider, Func<U, T> converter)
    {
        this.ElementName = ElementName;
        try
        {
           this.Value = converter(Provider());
        }
        catch (Exception e) {
           this.Exception = e;
        }
     }
    

    然后调用

    var result = new Result<List<Person>, Person[]>(
        "name", 
        GetPerson(), 
        p => new List<Person>(p));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-01
      • 2018-06-12
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多