C# 运算符重载
C# 运算符重载
重载一般定义为实现流行
面向对象编程概念的过程,例如多态性,这意味着一个名称具有不同的形式和实现。它允许变量或对象在执行代码时采用不同的形式。它主要用于当您希望方法属性与给定参数不相似时,而是希望在一个名称可以与不同类型的执行方法和属性一起使用时使用不同的执行顺序。这可以在具有不同类型参数及其计数的程序中实现。 C#中有各种类型的运算符重载方法。您将在本教程中方便地学习所有这些方法。
C# 中的运算符重载技术
C# 中的运算符重载可以使用不同形式的运算符来完成。但在继续使用这些技术之前,让我们考虑一下运算符的验证以及它们在执行运算符重载时如何使用。
语法
public static classname operator op (parameters)
{
// Code
}
for Unary Operator
public static classname operator op (t)
{
// Code
}
for Binary Operator
public static classname operator op (t1, t2)
{
// Code
}
运算符通常是一个关键字,用于实现运算符重载。需要注意的是,重载运算符的返回类型不能保持void。这意味着在执行运算符重载时,优先权始终掌握在过定义的实现手中。没有优先考虑预定义的实现。
因此,重载方法应该总是有一组不同的参数。它们的顺序和数量不应相同。它们类似于任何其他方法,但在用户定义方法的情况下,运算符的优先级和语法不能更改。左边的在二元运算符中称为成员,而右边是称为参数的对象。一旦您完成相同的实现,您就会理解这些概念。
要考虑的另一个重要实例是,在 C# 中,有一个称为 运算符函数 的特殊函数。此函数或方法必须始终是静态和公共的。它仅由值参数组成。外部参数和引用参数通常不允许作为运算符函数中的参数。应用运算符函数的一般形式遵循以下语法。
public static return_type operator op (argument list)
这里的op是用于重载的运算符,运算符是唯一需要的关键字。对于一元运算符,您将只为二元运算符传递一个参数和两个参数。同样重要的是要注意,至少一个参数应该是用户定义的、结构类型或类。让我们看看如何实现所有这些概念。
一元运算符重载
一元运算符情况下运算符重载的一般形式遵循下面给出的语法。
public static return_type operator op (Type t)
{
// Statements
}
这里的返回类型可以是任何东西,但对于+、-、~和.(dot)这样的操作符来说,它不应该是空的。返回此运算符的类型应为 整数 或 布尔 类型。重要的是要注意布尔运算符推出 true 和 false,因此只能成对重载。如果不这样做,就会发生编译错误,因为一个类通常会声明这个运算符而不声明另一个。
考虑以下程序,该程序显示了类 Complex 中的一元运算符可以如何被重载。
using System;
class Complex
{
private int x;
private int y;
public Complex()
{
}
public Complex(int i, int j)
{
x = i;
y = j;
}
public void ShowXY()
{
Console.WriteLine("{0} {1}", x, y);
}
public static Complex operator -(Complex c)
{
Complex temp = new Complex();
temp.x =-c.x;
temp.y =-c.y;
return temp;
}
}
class MyClient
{
public static void Main()
{
Complex c1 = new Complex(10, 20);
c1.ShowXY(); // displays 10 & 20
Complex c2 = new Complex();
c2.ShowXY(); // displays 0 & 0
c2 =-c1;
c2.ShowXY(); // diapls-10 &-20
}
}
二元运算符重载
要重载二元运算符,您必须寻找两个参数。您需要确保运算符之一应该是定义运算符的类或结构类型。如前所述,二元运算符不能返回 void,但它可以在实现重载时返回所有其他类型的值。可以使用以下语法显示二元运算符中运算符重载的一般形式。
public static return_type operator op (Type1 t1, Type2 t2)
{
//Statements
}
考虑以下示例代码,其中展示了二元运算符重载的工作原理。
using System;
class Complex
{
private int x;
private int y;
public Complex()
}
public Complex(int i, int j)
{
x = i;
y = j;
}
public void ShowXY()
{
Console.WriteLine("{0} {1}", x, y);
}
public static Complex operator +(Complex c1, Complex c2)
{
Complex temp = new Complex();
temp.x = c1.x + c2.x;
temp.y = c1.y + c2.y;
return temp;
}
}
class MyClient
{
public static void Main()
{
Complex c1 = new Complex(10, 20);
c1.ShowXY(); // displays 10 & 20
Complex c2 = new Complex(20, 30);
c2.ShowXY(); // displays 20 & 30
Complex c3 = new Complex();
c3 = c1 + c2;
c3.ShowXY(); // dislplays 30 & 50
}
}
请务必注意 == 等运算符。 !=, <>, <=, >= 只能成对重载。当使用它们重载二元算术运算符时,赋值运算符将自动重载。例如,如果你重载 + 运算符,它也会被隐式重载为 += 运算符。
运算符重载和继承
另一个例子是,即使你将重载运算符声明为静态,它们将继承派生类。发生这种情况是因为运算符的声明要求它是声明运算符的结构体或类。它便于操作员签名。因此,先前在派生类中声明的运算符不可能隐藏父类中已经存在的运算符。因此, new 修饰符不是可以考虑的选项,因为在声明运算符时不允许使用它们。可以使用下面给出的以下代码片段来显示此实例。
using System;
class Complex
{
private int x;
private int y;
public Complex()
{
}
public Complex(int i, int j)
{
x = i;
y = j;
}
public void ShowXY()
{
Console.WriteLine("{0} {1}", x, y);
}
public static Complex operator +(Complex c1, Complex c2)
{
Complex temp = new Complex();
temp.x = c1.x + c2.x;
temp.y = c1.y + c2.y;
return temp;
}
}
class MyComplex: Complex
{
private double x;
private double y;
public MyComplex(double i, double j)
{
x = i;
y = j;
}
public MyComplex()
{
}
public new void ShowXY()
{
Console.WriteLine("{0} {1}", x, y);
}
}
class MyClient
{
public static void Main()
{
MyComplex mc1 = new MyComplex(1.5, 2.5);
mc1.ShowXY();
MyComplex mc2 = new MyComplex(3.5, 4.5);
mc2.ShowXY();
MyComplex mc3 = new MyComplex();
//mc3 = mc1 + mc2;
//mc3.ShowXY();
}
}
相等运算符重载
您可能已经熟悉所有默认从 Syste.object.Equals() 方法继承 Syste.object 的用户定义类,在 C# 中。基于引用的比较由 Equals() 方法提供。但是这个方法有可能覆盖驻留在用户定义的类中的方法。因此,使用这种方法可以轻松实现基于价值的比较。这就是 Equality 运算符的操作方式。要重载此运算符,您需要遵循下面显示的以下代码片段。
using System;
class Complex
{
private int x;
private int y;
public Complex()
{
}
public Complex(int i, int j)
{
x = i;
y = j;
}
public void ShowXY()
{
Console.WriteLine("{0} {1}", x, y);
}
}
class MyClient
{
public static void Main()
{
Complex c1 = new Complex(10, 20);
c1.ShowXY(); // displays 10 & 20
Complex c2 = new Complex(10, 20);
c2.ShowXY(); // displays 10 & 20
Complex c3 = c2;
c3.ShowXY(); // dislplays 10 & 20
if (c1.Equals(c2))
Console.WriteLine("OK");
else
Console.WriteLine("NOT OK");
if (c2.Equals(c3))
Console.WriteLine("OK1");
}
}
在上面的程序中,结果显示为"NOT OJ"和"OK1"。这通常意味着默认情况下, Equals() 方法正在执行引用比较。需要注意的是,上面代码中对象C2和C1的值是一样的,只是在内存地址上有不同的偏好。但是如果您仔细注意,C2 和 C3 共享相同的内存引用。这就是 Equals() 方法实现相等运算符重载的方式。在 C# 中,也可以覆盖 Equals() 方法,即使它可能存在于用户定义的任何类中以实现基于值的比较。可以使用下面显示的以下代码片段来支持此语句。
using System;
class Complex
{
private int x;
private int y;
public Complex()
{
}
public Complex(int i, int j)
{
x = i;
y = j;
}
public void ShowXY()
{
Console.WriteLine("{0} {1}", x, y);
}
public override bool Equals(object o)
{
if ((Complex)o.x == this.x && (Complex)o.y == this.y)
return true;
else
return false;
}
public override int GetHashCode()
{
return this.ToString().GetHashCode();
}
}
class MyClient
{
public static void Main()
{
Complex c1 = new Complex(10, 20);
c1.ShowXY(); // displays 10 & 20
Complex c2 = new Complex(10, 20);
c2.ShowXY(); // displays 10 & 20
Complex c3 = c2;
c3.ShowXY(); // dislplays 10 & 20
if (c1.Equals(c2))
Console.WriteLine("OK");
else
Console.WriteLine("NOT OK");
if (c2.Equals(c3))
Console.WriteLine("OK1");
}
}
总结
在本教程中,您了解了通常用于在 C# 中实现运算符重载的整体方法。您遇到过使用一元、二元和等式运算符实现运算符重载的某些实例。您现在可能还很熟悉,在实现 C# 时,各种运算符会限制程序的流程,因此您需要了解它们在哪里花费这些条件。此外,在 C# 中实现运算符重载时,您需要非常好奇地了解实现时推出的数据的工作流程是什么,以及一种数据形式如何提供不同类型的输出。