C# 运算符重载

 网络编程     |      2019-11-21

访谈的运算符重载。。。。。。。。。。。。。。。。。。。。。。。。。。。

operator

operator 关键字用于在类或结构注明中扬言运算符。运算符注脚能够应用下列多样情势之风姿罗曼蒂克:

  1. public static result-type operator unary-operator ( op-type operand )

  2. public static result-type operator binary-operator (

        op-type operand,
        op-type2 operand2
        )
    
  3. public static implicit operator conv-type-out ( conv-type-in operand )

  4. public static explicit operator conv-type-out ( conv-type-in operand )

C# 运算符重载。参数:

  1. result-type 运算符的结果类型。
  2. unary-operator 下列运算符之风流罗曼蒂克:+ - ! ~ ++ — true false
  3. op-type 第二个(或唯生机勃勃四个卡塔尔国参数的门类。
  4. operand 第二个(或唯生龙活虎四个卡塔尔国参数的名目。
  5. binary-operator 在那之中二个:+ - * / % & | ^ << >> == != > <
    >= <=
  6. op-type2 次之个参数的类型。
  7. operand2 次之个参数的称号。
  8. conv-type-out 类型调换运算符的靶子项目。
  9. conv-type-in 类型转变运算符的输入类型。

注意:

  1. 前二种情势表明了顾客定义的重载内置运算符的运算符。并不是全部内置运算符都能够被重载(请参见可重载的运算符)。op-type 和 op-type2
    中足足有一个亟须是密闭类型(即运算符所属的花色,或明白为自定义的系列卡塔尔。比如,那将防御重定义整数加法运算符。
  2. 后三种样式表明了改换运算符。conv-type-in 和 conv-type-out
    中正好有三个必得是密闭类型(即,调换运算符只好从它的查封类型调换为此外有些项目,或从此外有个别类型转变为它的密封类型卡塔尔国。
  3. 运算符只好利用值参数,无法利用 ref 或 out太阳集团娱乐网址09055, 参数。
  4. C# 必要成对重载相比运算符。借使重载了==,则也必需重载!=,不然发生编写翻译错误。同一时间,相比运算符必得回到bool类型的值,那是与其余算术运算符的一直差别。
  5. C# 分裂意重载=运算符,但若是重载举个例子+运算符,编写翻译器会活动使用+运算符的重载来执行+=运算符的操作。
  6. 运算符重载的其实便是函数重载。首先通过点名的演算表明式调用对应的运算符函数,然后再将运算对象转变为运算符函数的实参,接着依照实参的门类来规定供给调用的函数的重载,那个历程是由编写翻译器完毕。
  7. 任何运算符申明的先头都能够有贰个可选的属性(C# 编制程序指南卡塔尔列表。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//简单的运算符重载 方便理解
namespace 运算符重载
{
    public class Money
    {
        public decimal Weight { get; set; }
        public static decimal operator -(Money a1, Money a2)//public static 必须要写上。operator是关键字
        {
            return a1.Weight - a2.Weight;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Money a = new Money { Weight = 100.00M };
            Money b = new Money { Weight = 200.66M };

            Console.Write(b - a);

            Console.Read();
        }
    }
}

explicit

explicit 关键字用于评释必得使用强制转变成调用的顾客定义的类型调换运算符。

static explicit operator target_type { source_type identifier }

 

参数:

 

  1. target_type 目的项目
  2. source_type 源类型。
  3. identifier Something。

 

注意:

 

  1. 转移运算符将源类型调换为对象项目。源类型提供调换运算符。与隐式调换分裂,必得透过强制转变的措施来调用显式转换运算符。固然调换操作大概导致十分或遗失音讯,则应将其标记为
    explicit。那足以免御编写翻译器无提醒地调用可能爆发不可能预言后果的调换操作。

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

implicit

implicit 关键字用于申明隐式的客商定义类型调换运算符。

static implicit operator target_type { source_type identifier }
注意:
  1. 隐式转变能够透过扫除不供给的类型转变到升高源代码的可读性。不过,因为能够在工程师未内定的情状下发生隐式调换,由此必需小心防御令人不欢愉的结局。一般景色下,隐式转变运算符应当未有引发那三个而且未有错过新闻,以便能够在程序猿不知晓的事态下安全使用它们。要是调换运算符不可能满足那贰个条件,则应将其标记为
    explicit。

示例:

以下是叁个综合示范,简要呈现用法。如要更实际细节的问询,请参阅MSDN Library。

//
keywords_operator.cs
// keywords_operator.cs

using System;

namespace Hunts.Keywords
{
    // 定义一个人民币结构。数据类型调换的语法对于协会和类是意气风发致的
    public struct RMB
    {
        // 注意:这么些数的范围大概不能够知足实际中的使用
        public uint Yuan;
        public uint Jiao;
        public uint Fen;

        public RMB(uint yuan, uint jiao, uint fen)
        {
            if (fen > 9)
            {
                jiao += fen / 10;
                fen = fen % 10;
            }
            if (jiao > 9)
            {
                yuan += jiao / 10;
                jiao = jiao % 10;
            }
            this.Yuan = yuan;
            this.Jiao = jiao;
            this.Fen = fen;
        }

        public override string ToString()
        {
            return string.Format("¥{0}元{1}角{2}分", Yuan, Jiao, Fen);
        }

        // 一些操作
        public static RMB operator +(RMB rmb1, RMB rmb2)
        {
            return new RMB(rmb1.Yuan + rmb2.Yuan, rmb1.Jiao + rmb2.Jiao, rmb1.Fen + rmb2.Fen);
        }

        public static implicit operator float(RMB rmb)
        {
            return rmb.Yuan + (rmb.Jiao/10.0f) + (rmb.Fen/100.00f);
        }

        public static explicit operator RMB(float f)
        {
            uint yuan = (uint)f;
            uint jiao = (uint)((f - yuan) * 10);
            uint fen = (uint)(((f - yuan) * 100) % 10);
            return new RMB(yuan, jiao, fen);
        }

        // more
    }
    class App
    {
        static void Main()
        {
            RMB r1, r2, r3, r4;

            // 记得小学时的某次捐款,作者把口袋里藏好的一元钱加6张一毛钱以致10个一分钱的硬币都贡献出去了:(
            r1 = new RMB(1, 6, 13);
            // 其实那时候别的人都曾经交过了,他们一同交了:
            r2 = new RMB(46, 9, 3);
            // 那么丰硕本人的就是:
            r3 = r1 + r2;
            Console.WriteLine("r3 = {0}", r3.ToString());

            // 隐式转换
            float f = r3;
            Console.WriteLine("float f= {0}", f);

            // 显式转变
            r4 = (RMB)f;
            Console.WriteLine("r4 = {0}", r4.ToString());
            //假设不开展浮现转换,将现出谬误 CS0266: 无法将项目“float”隐式调换为“Hunts.Keywords.毛子任”。存在一个显式调换(是或不是贫乏强制调换?)

            Console.Read();
        }
    }
}

/* style="color: #008000;">
调整台出口:
r3 = ¥48元6角6分
float f = 48.66
r4 = ¥48元6角5分
*/

我们会意识r4结果少了一分钱!那是因为在:

uint style="color: #000000;"> fen style="color: #000000;">= (uint style="color: #000000;">)(((f style="color: #000000;">- yuan) * style="color: #000000;">100) % style="color: #000000;">10 style="color: #000000;">);

那句中,在将float转变为uint时发生了圆整错误(这与Computer以二进制存储有关卡塔 尔(英语:State of Qatar)。解决这一个错误,大家能够运用System.Convert类中用来拍卖数字的静态方法:

uint style="color: #000000;"> fen style="color: #000000;">= Convert.ToUInt32(((f style="color: #000000;">- yuan) * style="color: #000000;">100) % style="color: #000000;">10 style="color: #000000;">);

只是使用System.Convert管理会有个别品质的损失。

 

 

正文转发自 C# 参考之转变关键字:operator、explicit与implicit

 

C#最广大的重载是构造函数重载,各类法子包涵ToString()也足以重载,运算符+-*/也足以重载,前几天大家就来讲说运算符重载。

一、简介
  C# 允许顾客定义的等级次序通过采纳 operator 关键字定义静态成员函数来重载运算符。注意必得用public修饰且必需是类的静态的方法。但毫无全数内置运算符都能够被重载,详见表1:
太阳集团娱乐网址09055 1

二、声明
  operator 关键字用于在类或组织注脚中评释运算符。运算符注解能够运用下列多样样式之生机勃勃:

public static result-type operator unary-operator ( op-type operand )

public static result-type operator binary-operator ( op-type operand, op-type2 operand2 )

public static implicit operator conv-type-out ( conv-type-in operand )

public static explicit operator conv-type-out ( conv-type-in operand )

  参数表明:

  result-type:运算符的结果类型。
  unary-operator:下列运算符之后生可畏:+ - ! ~ ++ — true false
  op-type:第四个(或唯大器晚成二个卡塔尔参数的连串。
  operand:第叁个(或唯大器晚成多个卡塔 尔(英语:State of Qatar)参数的称呼。
  binary-operator:在那之中叁个:+ - * / % & | ^ << >> == != > < >= <=
  op-type2:第三个参数的类别。
  operand2:第一个参数的名称。
  conv-type-out:类型调换运算符的靶子项目。
  conv-type-in:类型转变运算符的输入类型。

  注意:

  1、运算符重载的注明形式:operator 关键字告诉编写翻译器,它实际上是一个运算符重载,后边是连锁运算符的号子。

  2、运算符只好利用值参数,不能够利用ref或out参数。可参看注意事项生机勃勃实例。

  3、前二种样式阐明了客商定义的重载内置运算符的运算符。op-type 和 op-type2中最罕见贰个亟须是查封类型(即运算符所属的档期的顺序,或知道为自定义的连串卡塔尔。比方,那将堤防重定义整数加法运算符。可参照注意事项二实例。

  4、后三种情势申明了转移运算符。conv-type-in 和 conv-type-out 中无独有偶有一个亟须是查封类型(即转变运算符只可以从它的密封类型转变为其余某些项目,或从其余有个别类型调换为它的密封类型卡塔 尔(英语:State of Qatar)。

  5、对于二元运算符,第二个参数是投身运算符左边的值,常常命名叫lhs;第4个参数是身处运算符右侧的值,日常命名字为rhs。

  6、C#渴求有所的演算符重载都宣示为public和static,必需是类的静态方法,那意味它们与它们的类或组织相关联,而不是与实例相关联。

注意事项生机勃勃:
public class Student
{
public int Age { get; set; }
public string Name { get; set; }

        public Student()
        { }

        public Student(int age, string name)
        {
            this.Age = age;
            this.Name = name;
        }

        //语法错误:ref和out参数在此上下文中无效(去掉ref和out关键字即可).
        public static Student operator +(ref Student stu1,out Student stu2)
        {
            return new Student(stu1.Age + stu2.Age, stu1.Name + "+++" + stu2.Name);
        }
    }

注意事项二:
public class Student
{
public int Age { get; set; }
public string Name { get; set; }