如何正确重载运算符?

How to correctly overload operators?

我正试图在 class 中重载运算符。但我无法让它工作。 编译器向我发送了很多错误。喜欢:

CS0019:运算符“+”不能应用于 'T' 和 'T'

类型的操作数

CS1020:预期可重载二元运算符

这是我的代码:

//-------------------------------------------------- 

public class DataObject<T> 
{
    private T data;

    public static void operator =(DataObject<T> a, T b)
    {
         a.data = b;
    }
    public static DataObject<T> operator +(DataObject<T> a, DataObject<T> b)
    {
        return a.data + b.data;
    }

    public static T operator +(DataObject<T> a, T b)
    {
        return a.data + b;
    }
}

//-------------------------------------------------- 

public class Int : DataObject<int>
{     
}

//-------------------------------------------------- 

public class Calc
{
    public Int Add(Int a, Int b)
    {
        return a + b;
    }

    public void Add(Int a, Int b, Int result)
    {
        result = a + b;
    }
}

//-------------------------------------------------- 

public class EntryPoint
{
    static void Main()
    {
        Int a = new Int();
        Int b = new Int();
        Int result = new Int();

        Calc calc = new Calc();

        a = 5;
        b = 7;

        calc.Add(a, b, result);
        Console.Write("\n result=" + result);


        a = 3;
        b = 6;

        result = calc.Add(a, b);
        Console.Write("\n result=" + result);        

    }
}

谁能告诉我如何正确执行此操作?

注意:我只需要'T'是“int”或“float”数据类型。

谢谢!!

首先,您不能在 C# 中重载 = 运算符。 = 根本就不是 overloadable operators 之一。如果你想做这样的事情:

a = 5;
b = 7;

最接近的是使用隐式转换:

public static implicit operator DataObject<T>(T b) 
    => new DataObject<T> { data = b };

...

DataObject<int> a = 5;
DataObject<int> b = 7;

请注意,它的语义与按您想要的方式重载 = 运算符略有不同。这会创建 DataObject<int> 的新实例,而不是改变 abAdd 的第二次重载将无法正常工作。您必须使 result 成为 outref 参数。

此外,您的整个设计要求为 T 定义一个 + 运算符,但情况并非总是如此,并且没有 generic constraint 约束 T 到 C# 中的“已重载 + 运算符的类型”。

您似乎已将其设为通用,以免重复编写这些运算符的样板代码,但运算符确实 需要在每种类型中重新定义 - 如果它们是都继承自parent class,那么他们都会return parent class,而不是他们自己。 Int + Int 将 return 变成 DataObject<int>,而不是 Int。你真的想要那个吗? C# 没有 self-types 所以你不能告诉它“return 无论 subclass 是什么”。另外,将一种类型的 DataObject<int> 添加到另一种类型的 DataObject<int> 真的有意义吗?

无论如何,您的 Int 更适合作为 non-generic 结构:

public struct Int
{
    private int data;

    public static implicit operator Int(int b) => new Int { data = b };
    public static Int operator +(Int a, Int b) => new Int { data = a.data + b.data };

    public override string ToString() => data.ToString();
}

Calc可以这样:

public class Calc
{
    public Int Add(Int a, Int b) =>  a + b;

    public void Add(Int a, Int b, out Int result)
    {
        result = a + b;
    }
}

最后Main可以这样:

Int a = 5;
Int b = 7;
Int result;

Calc calc = new Calc();

calc.Add(a, b, out result);
Console.Write("\n result=" + result);


a = 3;
b = 6;

result = calc.Add(a, b);
Console.Write("\n result=" + result);