简体   繁体   English

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

[英]How can I subtract two generic objects (T - T) in C# (Example: DateTime - DateTime)?

I wrote a Generic Class : 我写了一个通用类

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

And I use this class with DateTime, int, etc. 我使用这个类与DateTime,int等。

I need a Duration property that returns a duration like: 我需要一个Duration属性,返回一个持续时间,如:

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

But when this property is included in my class, the compiler raises a logical error on the - operator. 但是当我的类中包含此属性时,编译器会在-运算符上引发逻辑错误

What can I do to achieve this goal normally, or should I ignore it? 我能做些什么来正常实现这个目标,还是应该忽略它?

This is not possible with generics in C# - at least not directly. 对于C#中的泛型,这是不可能的 - 至少不是直接的。 It has been a highly requested feature on Connect for a long time. 长期以来,它一直是Connect上一项备受关注的功能

You will need to make your types implement some interface that has a member that can be used, and constrain the class to that, or use one of the workarounds listed in the Connect bug (none of which are perfect), or a separate approach like MiscUtil's generic operators . 您需要使您的类型实现一些具有可以使用的成员的接口,并将类约束到该类,或者使用Connect错误中列出的解决方法之一(没有一个是完美的),或者使用单独的方法MiscUtil的通用运算符

this work 这项工作

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

but no check, and slow 但没有检查,而且很慢

Try something like this: 尝试这样的事情:

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

How this works: first, you convert the arguments to a dynamic type, and you can easily use operators on the dynamic type. 这是如何工作的:首先,您将参数转换为动态类型,并且您可以轻松地在动态类型上使用运算符。 If you wouldn't be able to use the operators, then an exception would be thrown at runtime. 如果您无法使用运算符,则会在运行时抛出异常。 So, if you try to substract two objects that you actually can't substract, we'll catch the exception and return false as the second item in the Tuple . 因此,如果您尝试减去实际上无法减去的两个对象,我们将捕获异常并返回false作为Tuple的第二项。

Check Jon Skeet's Misc Util https://jonskeet.uk/csharp/miscutil/ 查看Jon Skeet的Misc Util https://jonskeet.uk/csharp/miscutil/

And here the generic operators by Marc Gravell: https://jonskeet.uk/csharp/miscutil/usage/genericoperators.html 这里是Marc Gravell的通用运算符: https ://jonskeet.uk/csharp/miscutil/usage/genericoperators.html

The compiler does this so you don't write buggy code, its the whole point of generics and the concept of type safe programming. 编译器执行此操作,因此您不会编写错误的代码,它是泛型的全部要点和类型安全编程的概念。

If you need a method that subtracts dates write one that accepts a date, and if you need another one for integers, guess what you should write one for integers. 如果你需要一个减去日期的方法写一个接受日期的方法,如果你需要另一个用于整数,猜猜你应该为整数写一个。 Generics are not there so that the compiler can assume responsibility for any type. 泛型不存在,因此编译器可以承担任何类型的责任。 Think about it what if I wanted the difference between two objects, how would I do that with your generic method? 想一想,如果我想要两个对象之间的差异,我将如何使用您的泛型方法做到这一点?

Or as @Reed Copsey mentioned you can constrain a class to it. 或者正如@Reed Copsey所提到的,你可以将一个类限制为它。

While this may seem like a major restriction, you need to remember that generics are generic. 虽然这似乎是一个主要限制,但您需要记住泛型是通用的。 Of course, the System.Int32 type can work just fine with the binary operators of C#. 当然, System.Int32类型可以与C#的二元运算符一起使用。 However, for the sake of argument, if <T> were a custom class or structure type, the compiler cannot assume it has overloaded the + , - , * , and / operators. 但是,为了参数,如果<T>是自定义类或结构类型,编译器不能假设它已经重载了+-*/运算符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM