在C#中混合动力学和泛型

时间:2015-01-23 19:23:28

标签: c# generics

我正在用C#编写一个函数。我的函数需要根据类型确定一组值的范围。我将在未来支持更多类型,这就是我想要一个通用函数的原因。目前,我只考虑Int32DateTime。目前,我有以下内容:

private void GetRange<T>(List<Value> list, out dynamic absoluteMin, out dynamic absoluteMax, out dynamic begin, out dynamic mean out dynamic finish)
{
  T tempMin = default(T);
  T tempMax = default(T);

  begin = tempMin;
  if (tempMin is Int32) 
  {
    absoluteMin = Int32.MinValue;
    begin = Int32.MinValue;
    finish = Int32.MaxValue;
    absoluteMax = Int32.MaxValue;
  }
  else if (tempMin is DateTime)
  {
    absoluteMin = DateTime.MinValue;
    begin = new DateTime(2000, 1, 1);
    end = DateTime.Today;
    absoluteMax = DateTime.MaxValue;
  }

  foreach (var item in list)
  {
    var value = item.Value;
    if (tempMin is DateTime)
    {
      // ...
    }
    // determine begin and end of values in the list
  }
}

我这样称呼这个方法:

dynamic min = null;
dynamic max = null;
dynamic start = null;
dynamic end = null;

var useInt = ShouldIUseInt();
if (useInt)
  GetRange<Int32>(myList, min, max, start, end);
else
  GetRange<DateTime>(myList, min, max, start, end);

调用该方法时,会抛出一个运行时错误,其中包含以下内容:

The best overloaded method match for 'myClass.GetRange<System.DateTime>
(System.Collections.Generic.List<Value>, out object, out object, out object, out object)' 
has some invalid arguments

我不明白为什么我会收到此运行时错误或如何修复它。任何帮助表示赞赏。谢谢。

1 个答案:

答案 0 :(得分:1)

你真的不想沿着这条将不同目的结合到一个单一功能的路线。更好的方法是从结果中制作通用,然后创建一个扩展类来汇总结果。

using System.Linq;

public class Range<T>
{
   public T Min { get; private set; }
   public T Max { get; private set; }

   public Range(T min, T max) 
   {
      Min = min;
      Max = max;
   }
}

public static class RangeExtensions
{
    public static Range<T> GetRange<T>(this List<T> values)
    {
        return new Range<T>(values.Min(), values.Max());
    }
}

您可以在任何包含可实现IComparable<T>的基本类型和类型的列表中调用此方法:

 List<int> intList = new List<int> { 1, 2, 3, 4, 5 };
 List<DateTime> dateList = new List<DateTime> { DateTime.Now, DateTime.Now.AddDays(3), DateTime.Now.AddDays(5) };

 var intRange = intList.GetRange ();
 var dateRange = dateList.GetRange ();