65.9K
CodeProject 正在变化。 阅读更多。
Home

C# .NET 中的运算符重载

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.33/5 (11投票s)

2011 年 4 月 8 日

CPOL

2分钟阅读

viewsIcon

84185

downloadIcon

1

本文概述了在 .NET 中使用 C# 进行运算符重载的方法。

运算符

运算符重载也称为重载,它提供了一种为用户定义的类或结构定义和使用运算符(例如 +、- 和 /)的方法。 它还允许我们定义/重新定义运算符如何与我们的类和结构一起工作。 这样,这项技术使程序员可以使他们的自定义类型看起来和感觉起来像简单的类型,例如 intstring。 它基本上只包含一个由关键字 operator 声明并后跟运算符的方法。 主要有三种类型的可重载运算符,称为一元、二元和转换。 但并非每种类型的所有运算符都可以重载。 让我们在下面更详细地介绍每种类型的运算符。

重载一元运算符

一元运算符是那些只需要单个操作数/参数进行操作的运算符。 参与运算的类或结构必须包含运算符声明,它们包括 +-!~++--truefalse。 重载一元运算符时,适用以下规则

  • +-!~ 必须采用定义类型的参数,并且可以返回任何类型
  • ++- 必须采用并返回定义类型
  • truefalse 必须采用定义类型的参数,并且可以返回一个 bool

简而言之,为标准 C# 运算符赋予相对于用户定义数据类型(如类或结构)的特殊含义的机制称为运算符重载。

  • 所有 C# 二元运算符都可以重载。即,+-*/%&|<<>>
  • 所有 C# 一元运算符都可以重载。即,+_!++--
  • 所有关系运算符都可以重载,但只能成对重载。即,= =!=<><=>=

简单来说,假设 + 被重载。 如果你想找到 a + b

  • 如果 a,b 是整数,那么结果将是 ab 的和,结果是 int
  • 如果 a,bfloat,那么结果将是 ab 的和,结果是 float
  • 如果 a,b 是两个 string,那么结果将是 String aString b 的连接,最终结果是 string

这样,+ 会根据数据进行不同的操作重载。

源代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OperatorOverloading
{
    class Rectangle
    {
        static void Main(string[] args)
        {
            Rectangle objRect1 = new Rectangle(10);
            Rectangle objRect2 = new Rectangle(20);
            Rectangle objRect3 = objRect1 + objRect2; 	// Calls operator + 
						// (Rectangle,Rectangle)
            Console.WriteLine(objRect3);
            Console.WriteLine(objRect3 + 15); // Calls operator + 
					// (Rectangle,int) and then ToString()
            Console.WriteLine(objRect3 + 2.5);// Calls operator + 
					// (Rectangle,double) and then ToString()
            objRect3 = 10; // Calls operator Rectangle(int)
            Console.WriteLine(objRect3);
            Rectangle objRect4 = 10;
            Console.WriteLine(objRect1 == objRect4); //Calls == operator
            Console.WriteLine(objRect1 != objRect4); //Calls != operator
            Console.WriteLine(objRect1 > objRect2); //Calls > operator
            Console.WriteLine(objRect1 <= objRect4); //Calls <= operator
        }

        private double Side;
        
        //public Constructor if int is passed convert to double and assign to Side
        public Rectangle(int objRect)
        {
        Console.WriteLine("Int->Double->Assign to Side");
        Side=(double)objRect;
        } 
        //OverLoaded constructor with double argument
        public Rectangle(double objRect)
        {
        Console.WriteLine("Double->Assign to Side");
        Side = objRect;
        } 
        //override ToString() method of object class.
        public override string ToString()
        {
        Console.WriteLine("Override object class's string");
        return this.Side.ToString();
        } 
        //Overloading + operator to add 2 Rectangle objects 
        //and return new Rectangle object
        public static Rectangle operator + (Rectangle x,Rectangle y)
        {
        Console.WriteLine("Overloading + with Rectangle,Rectangle");
        return new Rectangle(x.Side+y.Side);
        Console.WriteLine("");
        } 
        //Overloading + operator to add Rectangle objects with double side and 
        //return new Rectangle object
        public static Rectangle operator + (Rectangle x,double y)
        {
        Console.WriteLine("Overloading + with Rectangle,double");
        return new Rectangle(x.Side+y);
        } 
        
        //Overloading + operator to add Rectangle objects with int side 
        //and return new Rectangle object
        public static Rectangle operator + (Rectangle x,int y)
        {
        Console.WriteLine("Overloading + with Rectangle,int");
        return x +(double)y;
        } 

        public static implicit operator Rectangle(double s)
        {
        Console.WriteLine("Overloading = for Rectangle objRect5=1.5 assignment");
        return new Rectangle(s);
        } 
        
        public static implicit operator Rectangle(int s)
        {
        Console.WriteLine("Overloading = for Rectangle objRect5=10 assignment");
        return new Rectangle((double)s);
        } 
        
        //OverLoading == operator
        public static bool operator ==(Rectangle x,Rectangle y)
        {
        Console.WriteLine("Overloading == with Rectangle,Rectangle");
        return x.Side==y.Side;
        }
        
        //OverLoading != operator
        public static bool operator !=(Rectangle x,Rectangle y)
        {
        Console.WriteLine("Overloading != with Rectangle,Rectangle");
        return !(x==y); //This will call to operator == simple way to implement !=
        } 
        
        //Always override GetHashCode(),Equals when overloading ==
        public override bool Equals(object obj)
        {
        return this==(Rectangle)obj;
        } 
        
        public override int GetHashCode()
        {
        return (int)Side;
        } 
        
        //OverLoading > operator
        public static bool operator >(Rectangle x,Rectangle y)
        {
        Console.WriteLine("Overloading > with Rectangle,Rectangle");
        return x.Side>y.Side;
        } 
        
        //OverLoading < operator
        public static bool operator <(Rectangle x,Rectangle y)
        {
        Console.WriteLine("Overloading < with Rectangle,Rectangle");
        return x.Side= operator
        public static bool operator >=(Rectangle x,Rectangle y)
        {
        Console.WriteLine("Overloading >= with Rectangle,Rectangle");
        return (x>y) || (x==y); //Calls to operator == and >
        } 
        
        //Readonly Property
        public double Area
        {
            get
            {
                return 2*Side;
            }
        } 
    }
}

历史

  • 2011 年 4 月 7 日:初始版本
© . All rights reserved.