C# 对运算符重载感到困惑吗
当我在学习我的小数学库时,我遇到了C#和.NET框架的某些方面,我在理解这些方面遇到了一些困难 这次是运算符重载,特别是术语重载本身。为什么称之为重载?默认情况下,所有对象是否都有所有运算符的实现?即是:C# 对运算符重载感到困惑吗,c#,operator-overloading,C#,Operator Overloading,当我在学习我的小数学库时,我遇到了C#和.NET框架的某些方面,我在理解这些方面遇到了一些困难 这次是运算符重载,特别是术语重载本身。为什么称之为重载?默认情况下,所有对象是否都有所有运算符的实现?即是: public static object operator +(object o1, object o2) 不知何故?如果是这样,为什么如果我尝试o1+o2我会得到编译时错误运算符“+”不能应用于“object”和“object”类型的操作数?这在某种程度上意味着默认情况下对象没有预定义的操
public static object operator +(object o1, object o2)
不知何故?如果是这样,为什么如果我尝试o1+o2
我会得到编译时错误运算符“+”不能应用于“object”和“object”类型的操作数
?这在某种程度上意味着默认情况下对象没有预定义的操作符,那么术语重载是怎么来的呢
我问这个问题,因为在我的数学库中,使用3D几何元素,我有以下结构:向量
和点
。现在,我想在内部允许以下构造创建向量:
static Vector operator -(Point p1, Point p2) {...}
由于这在数学上不是100%正确的,但在内部对减少代码混乱非常有用,因此我不想公开此运算符,因此我最初的意图只是:
internal static Vector operator -(Point p1, Point p2) {...}
令人惊讶的是(对我来说)我得到了以下编译时错误:用户定义操作符'Geometry.operator+(Geometry.Vector,Geometry.Vector)'必须声明为静态和公共的
”
现在,所有运营商必须公开的限制似乎对运营商的整个过载方面有一定的意义,但似乎有点不一致:
+
运算符,我无法在默认情况下执行object+object
,或者执行myTpye+myType
操作符的访问修饰符,它们必须是公共的
,考虑到第1点,这是没有意义的。但考虑到第2点,这有点意义
object+object
,因为必须在其中一个操作数的类型中声明运算符;Point+Point
必须在Point
中声明;您不能定义object+object
,因为您没有声明object
;请注意,所有对象都具有(至少在语言级别)=
/!=
运算符==
/=代码>运算符,或从非平凡层次结构继承运算符的位置
公共的
,因此要么使它们成为公共的
,要么使用非操作员的内部的
方法publicstaticobjectoperator+(objecto1,objecto2)
没有
这在某种程度上意味着默认情况下对象没有预定义的操作符,那么术语重载是怎么来的呢
我不明白这个问题。当然,C#有预定义的运算符
我不想公开这个操作员
然后不要使用操作员;创建私有、内部或受保护的方法
C#的设计是,运算符始终是类型的公共表面积的一部分。如果运算符的含义取决于其使用所在的可访问性域,则会非常混乱。C#被精心设计成一种“质量陷阱”语言,语言设计者的选择使您远离编写混乱、有缺陷、难以重构的程序。要求用户定义的操作符是公共的和静态的是这些微妙的设计要点之一
(1) 默认情况下,对象没有预定义的运算符
当然是这样;在各种对象上有数百个预定义操作符。此外,例如,运算符+
有以下预定义的重载:
int + int
uint + uint
long + long
ulong + ulong
double + double
float + float
decimal + decimal
enum + underlying (for any enum type)
underlying + enum
int? + int?
uint? + uint?
long? + long?
ulong? + ulong?
double? + double?
float? + float?
decimal? + decimal?
enum? + underlying?
underlying? + enum?
string + string
object + string
string + object
delegate + delegate (for any delegate type)
有关所有其他运算符的所有预定义重载的列表,请参阅C#规范
请注意,运算符的重载解析有两个阶段:第一,重载解析尝试查找唯一的、最好的用户定义的重载;只有当这样做没有发现适用的候选项时,重载解析才会考虑预定义重载
(2) 定义运算符并不是说创建运算符,而是说重载(对我来说)与第1点不一致
我不明白你为什么觉得它不一致,或者,就这一点而言,你觉得什么不一致。术语“过载”一致用于描述操作员和方法;在这两种情况下,它都意味着
public class Fruit
{
protected static Shape operator +(Fruit f, Animal a) { ... }
}
public class Apple : Fruit
{
...
Shape shape = this + giraffe; // Legal!
}
public class Giraffe : Animal
{
...
Shape shape = apple + this; // Illegal!
}
public class Parent
{
public sealed void Foo(int n) { }
}
public class Child : Parent
{
public sealed void Foo(string s) { }
}
public class Parent
{
public virtual int Foo() { return 0; }
}
public class Child : Parent
{
public override int Foo() { return 1; }
}