如何正确重载运算符?
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>
的新实例,而不是改变 a
和 b
。 Add
的第二次重载将无法正常工作。您必须使 result
成为 out
或 ref
参数。
此外,您的整个设计要求为 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);
我正试图在 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>
的新实例,而不是改变 a
和 b
。 Add
的第二次重载将无法正常工作。您必须使 result
成为 out
或 ref
参数。
此外,您的整个设计要求为 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);