【问题标题】:C# Class using double Generics: give only one when both of them should be the same?使用双泛型的 C# 类:当它们都应该相同时只给出一个?
【发布时间】:2019-01-22 12:40:50
【问题描述】:

所以我在处理某段代码时有点吃力,我不确定是否有更好的方法来处理它 - 但感觉这是可能的。

假设我有一堂课:

public class DeviceProcessingResult<TSucceeded, TFailed>
    {
        public TSucceeded[] Succeeded { get; set; }

        public TFailed[] Failed { get; set; }

        public DeviceProcessingResult(IEnumerable<TSucceeded> succeeded, IEnumerable<TFailed> failed)
        {
            Succeeded = succeeded.Cast<TSucceeded>().ToArray();
            Failed = failed.Cast<TFailed>().ToArray();
        }
    }

我使用这个类来创建对象,这些对象包含一个处理成功的对象数组和一个失败的对象数组。这种类型的对象被用于我们当前拥有的代码的各个部分。在其中一个地方,我们会这样使用它:

return new DeviceProcessingResult<DeviceResponse, DeviceModel>(succeeded, failed);

由于我们需要返回结果,并且处理成功时返回的对象类型包含比处理失败时返回的模型其他/更多的信息。

现在这是目前唯一具有 2 种不同类型对象的代码,因为所有其他代码如下所示:

return new DeviceProcessingResult<DeviceModel, DeviceModel>(succeeded, failed);

如您所见,我们使用了 2 次相同的对象。

现在这个问题的重点是:有没有可能做类似的事情

return new DeviceProcessingResult<DeviceModel>(succeeded, failed);

反正那里的东西都是一样的吗?或者没有(好的)方法可以解决这个问题,我们是否应该始终指定这两种类型?

【问题讨论】:

  • 我相信你可以像return new DeviceProcessingResult(succeeded, failed); 一样调用它,并且类型将从传入的参数类型中推断出来
  • 为什么需要.Cast&lt;TSucceeded&gt;()

标签: c# .net generics


【解决方案1】:

简单的解决方案是像这样简单地继承这个类:

public class DeviceProcessingResult<T> : DeviceProcessingResult<T, T>
{
    public DeviceProcessingResult(IEnumerable<T> succeeded, IEnumerable<T> failed)
        : base(succeeded, failed)
    { /*Nothing more to do here...*/ }
}

public class DeviceProcessingResult<T, T1>
{
    public T[] Succeeded { get; set; }
    public T1[] Failed { get; set; }

    public DeviceProcessingResult(IEnumerable<T> succeeded, IEnumerable<T1> failed)
    {
        Succeeded = succeeded.ToArray();
        Failed = failed.ToArray();
    }
}

【讨论】:

  • @MarcoSalerno 我真的不明白为什么你认为我的答案还应该包含问题中代码的副本(略有改进)。
  • 因为新手不太清楚,这样他们才能更好地理解你所做的事情
  • 感谢您的回答!这很可能是要走的路,我已经在想它必须是那条线上的东西......
  • @MarcoSalerno 好的,我想可能是这样的。
  • @otomo 如果答案解决了您的问题,您应该接受它,以便其他人知道问题已解决。
【解决方案2】:

为此,您需要有另一个中间类,例如:

public class public class DeviceProcessingResult<TDeviceModel> 
    : DeviceProcessingResult<TDeviceModel, TDeviceModel>
{
}

或者,您可以依靠编译器根据参数推断类型:

return new DeviceProcessingResult(succeeded, failed)

【讨论】:

    【解决方案3】:

    怎么样:

        public class DeviceProcessingResult<TFailed> : DeviceProcessingResult< DeviceResponse, TFailed>
        {
            public DeviceProcessingResult(IEnumerable<DeviceResponse> succeeded, IEnumerable<TFailed> failed) : base(succeeded, failed)
            {
            }
        }
    

    【讨论】: