如何在C#中减去两个通用对象(T-T)(例如:DateTime – DateTime)?

我写了一个通用类

public class Interval where T : IComparable // for checking that Start < End { public T Start { get; set; } public T End { get; set; } ... } 

我将这个类与DateTime,int等一起使用。

我需要一个Duration属性,返回一个持续时间,如:

 public object Duration { get { return End - Start; } } 

但是当我的类中包含此属性时,编译器会在-运算符上引发逻辑错误

我能做些什么来正常实现这个目标,还是应该忽略它?

尝试这样的事情:

 static void Main(string[] args) { Tuple value = JustAMethod(5, 3); if (value.Item2) { Console.WriteLine(value.Item1); } else { Console.WriteLine("Can't substract."); } } public static Tuple JustAMethod(T arg1, T arg2) { dynamic dArg1 = (dynamic)arg1; dynamic dArg2 = (dynamic)arg2; dynamic ret; try { ret = dArg1 - dArg2; return new Tuple(ret, true); } catch { return new Tuple(default(T), false); } } 

这是如何工作的:首先,您将参数转换为动态类型,并且您可以轻松地在动态类型上使用运算符。 如果您无法使用运算符,则会在运行时抛出exception。 因此,如果您尝试减去实际上无法减去的两个对象,我们将捕获exception并返回false作为Tuple的第二项。

对于C#中的generics,这是不可能的 – 至少不是直接的。 长期以来,它一直是Connect上一项备受关注的function 。

您将需要使您的类型实现一些具有可以使用的成员的接口,并将类约束到该类,或者使用Connect错误中列出的解决方法之一(没有一个是完美的),或者像MiscUtil的通用运算符 。

这项工作

 public object Duration { get { return (dynamic)End - (dynamic)Start; } } 

但没有检查,而且很慢

查看Jon Skeet的Misc Util http://www.yoda.arachsys.com/csharp/miscutil/

这里是Marc Gravell的通用运营商: http : //www.yoda.arachsys.com/csharp/miscutil/usage/genericoperators.html

编译器执行此操作,因此您不会编写错误代码,它是generics的全部内容和类型安全编程的概念。

如果你需要一个减去日期的方法写一个接受日期的方法,如果你需要另一个用于整数,猜猜你应该为整数写一个。 generics不存在,因此编译器可以承担任何类型的责任。 想一想,如果我想要两个对象之间的差异,我将如何使用您的通用方法做到这一点?

或者正如@Reed Copsey所提到的那样,你可以将类限制为它。

虽然这似乎是一个主要限制,但您需要记住generics是通用的。 当然, System.Int32类型可以与C#的二元运算符一起使用。 但是,为了参数,如果是自定义类或结构类型,编译器不能假设它已经重载了+-*/运算符。