粗略的操作符重载,关于操作符重载与转移
分类:计算机编程

 随意写写

1.索引器方法协会大要上为<modifier><return type> this [argument list],它能够在接口中定义:  在为接口表明索引器的时候,记住证明只是表示索引器的存在。你只需求提供方便的拜访函数就可以,不必包含约束修饰符。以下代码把索引器注解为接口IImplementMe的黄金年代局地:

那一个操作符重载很有趣

      一人的成功有时往往体以往细节上,而习于旧贯往往是那么些细节的具体展现情势,这里本身也想计算多少个不太好的编制程序习贯。

 

interface IImplementMe {  string this[int index]  {  get;  set;  } 

class Program
{
static void Main(string[] args)
{
Person person1 = new Person() { Name = "LiLei", Age = 12 };
Person person2 = new Person("HanMeimei", 11);
Person person3 = person1 person2;
Person person4 = person1 == person2;
Person person5 = 10;
Console.WriteLine($"Name's merge is {person3.Name}nAge's sum is {person3.Age}");
Console.ReadKey();
}
}

      第一:下边包车型客车黄金年代段程序大概的情趣正是,页面上有二个特性HighPrice,它聊起底会透过ViewState保存在页面中,假诺ViewState为空,则设置属性HighPrice的值为-1,不然直接读取ViewState中的值。但其实际情况形并非那样,程序在最早化时,假诺ViewState["HighPrice"]奇异的写入了些非数字字符串数字,程序就能抛出特别。

率先,假设大家有三个Person类型

相应达成的类则必得为IimplementMe的索引器材体定义get和set访谈函数。

public class Person
{
public Person() { }
public Person(string name, int age)
{
this.Name = name; this.Age = age;
}
public string Name { get; set; }
public int Age { get; set; }
public static Person operator (Person p1, Person p2)
{
Person p3 = new Person(p1.Name p2.Name, p1.Age p2.Age);
return p3;
}

public int HighPrice {
  get
  {
    if (ViewState["HighPrice"] != null)
       return (int)ViewState["HighPrice"];
    else
       return -1;
  }
   set
   {
       ViewState["HighPrice"] = value;
   }
}

其类型定义如下

索引器能够称之为有参数的质量,它与天性的分别在于属性名称不能够长期以来,不可重载,索引器能够。属性可以使static的,可是索引器必得是实例化的。在我眼里索引器的效劳在于能够转移现存的某些索引器的目录方式,例如数组的所以措施是以int作为下标,查询相应数据,可是本人得以重写索引,使数组的目录以string进行。

public static Person operator ==(Person p1, Person p2)
{
Person p3 = new Person(p1.Name p2.Name, p1.Age p2.Age);
return p3;
}
public static Person operator !=(Person p1, Person p2)
{
Person p3 = new Person(p1.Name p2.Name, p1.Age p2.Age);
return p3;
}

      解决方案:上边给出相对科学的写法。大家只要有越来越好的写法能够建议仿照效法下。
      说明:(int)ViewState["HighPrice"]这种写法和int.TryParse(ViewState["HighPrice"].ToString(), out _HighPrice);还只怕有是比不小的分化的,因为ViewState["HighPrice"]对象要确定保障是数字字符串才行,假诺非常的大心给它赋值为空,那么就能够现身非常。不要过份相信二个对象的数据类型,极其是这种object类型的,那样写出的主次不完备。

  class Person
    {
        public string Name { get; set; } = "Person";
        public int Age { get; set; } = 18;

        public Person() { }

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

        public Person(string name) : this(name, 18) { }
        public Person(int age) : this("Person", age) { }


    }

例:

public static implicit operator Person
{
return new Person();
}
}

private int _HighPrice = -1;
        public int HighPrice
        {
            get
            {
                if (null != ViewState["HighPrice"])
                {
                  int.TryParse(ViewState["HighPrice"].ToString(), out _HighPrice);
                }
                return this._HighPrice;
            }
            set
            {
                this._HighPrice = value;
                if (null == ViewState["HighPrice"])
                {
                    this._HighPrice = -1;
                }
                //把变量值保存到ViewState中
                ViewState["HighPrice"] = this._HighPrice;
            }
        }

在例市价况下,大家让八个Person类型相加,是不或者的,比方:

namespace Study
{
    class Program
    {
        static void Main(string[] args)
        {
            ScoreIndex s = new ScoreIndex();
            s["张三", 1] = 90;
            s["张三", 2] = 100;
            s["张三", 3] = 80;
            s["李四", 1] = 60;
            s["李四", 2] = 70;
            s["李四", 3] = 50;
            Console.WriteLine("张三课程编号为1的大成为:" s["张三",1]);
            Console.WriteLine("张三的有所战绩为:");
            ArrayList temp;
            temp = s["张三"];
            foreach (IndexClass b in temp)
            {
                Console.WriteLine("姓名:" b.Name "课程编号:" b.CourseID "分数:" b.Score);
            }
            Console.ReadKey();
        }
    }
    class IndexClass
    {
        private string _name;
        private int _courseid;
        private int _score;
        public IndexClass(string _name, int _courseid, int _score)
        {
            this._name = _name;
            this._courseid = _courseid;
            this._score = _score;
        }
        public string Name
        {
            get { return _name; }
            set { this._name = value; }
        }
        public int CourseID
        {
            get { return _courseid; }
            set { this._courseid = value; }
        }
        public int Score
        {
            get { return _score; }
            set { this._score = value; }
        }
    }
    class ScoreIndex
    {
        private ArrayList arr;
        public ScoreIndex()
        {
            arr = new ArrayList();
        }
        public int this[string _name, int _courseid]
        {
            get
            {
                foreach (IndexClass a in arr)
                {
                    if (a.Name == _name && a.CourseID == _courseid)
                    {
                        return a.Score;
                    }
                }
                return -1;
            }
            set
            {
                arr.Add(new IndexClass(_name, _courseid, value)); //arr["张三",1]=90
            }
        }
        //重载索引器
        public ArrayList this[string _name]
        {
            get
            {
                ArrayList temp = new ArrayList();
                foreach (IndexClass b in arr)
                {
                    if (b.Name == _name)
                    {
                        temp.Add(b);
                    }
                }
                return temp;
            }
        }
    }
}

 

图片 1

2.操作符重载:

      //其次:对于多规格的论断,最规范的要数&&操作符了。黄金年代旦贰个讲话的实行必要同一时候满足多个条件,大家平常会如此写:if(条件生龙活虎&&条件二),意图是以为规范风度翩翩和规范化二都等于true的境况下,但事实上景况是假诺多个人原则//都以false,那么最后的准绳生龙活虎&&条件二的结果刚巧也是true,那个时候就能够现出不可预测的不当。况且这种张冠李戴也是可怜难查找的。不常候写代码能省就省,无法省的贰个也不可能少。

那么哪些能让五个Person类型相加,然后回来叁个Person类型呢

操作符重载是将长存的部分操作符的效劳举办改变,举例八个类相加,相减,相比较等,它提供Operaor关键字张开重载,必需与static关键字联合利用。例:

      //说明: 1:此条对C#不成立,但任何的言语就不自然,我们能够测量检验下。

举例说,作者想让名为"张三"年龄为19的Person加上另一个名称叫"李四",年龄为20的Person

namespace ContainerAndOperator
{
    /// <summary>
    /// 索引器,此类已化作容器类,索引器大多数运用在容器类中
    /// 使用IEnumerable与GetEnumerator()意在使那个类能够开展foreach
    /// </summary>
    public class ContainerClass : IEnumerable
    {
        private ArrayList people = new ArrayList();
        public Person this[int index]//Person为回去的值类型,int为输入的索引值的门类,this用来定义索引器
        {
            get { return (Person)people[index]; }
            set { people.Insert(index, value); }
        }

               //2:由于此条并不适用于主流的言语,写在这里有一点让园友糊涂,这里表示道歉,但在某种景况上实在存在,起码笔者碰着过,这里并不要求大家同意作者的眼光,信则有不相信则无,唯有当你实在会见过才会有越来越深的咀嚼。

接下来回来叁个名称叫"张三吕四",年龄为39的Person

        public IEnumerator GetEnumerator()
        {
            return people.GetEnumerator();
        }
    }

     更新:下面的第二条我们都不太承认,不过小编遇见的景观和这篇随笔大致: ,大家能够参见下,有园友说是因为firebug的二个BUG,这里自身特把那条注释掉,这里未有像园友说的嘴硬不认同错误,而是有的时候候确实某个不便解释的风貌出现,何况当改换相应的写法后当真原有的BUG子虚乌有。

那么就须要使用重载" "号那么些操作符了

    public class Person
    {
        public string name { get; set; }
        public string Id { get; set; }
        public int Age { get; set; }
        /// <summary>
        /// 重构二元操作符
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <returns></returns>
        public static Person operator (Person p1,Person p2)
        {
            return new Person(p1.name "-" p2.name, p1.Id "-" p2.Id, p1.Age p2.Age);
        }
        public static string operator -(Person p1, Person p2)
        {
            return p1.name "-" p2.Id;
        }
        public Person(){}
        public Person(string n,string i,int a)
        {
            name = n;
            Id = i;
            Age = a;
        }
    }
}

      其三:对于if语句的写法。小编们基本上会这么写:if(条件==true),平常状态下是绝非难题,但临时会写成if(条件=true),也正是程序员在写的时候少写了二个等号,形成程序恒久施行上面包车型地铁代码,这种指鹿为马查找起来也是非常辛劳的,因为编写翻译器在编写翻译时并不会报错。

故此,代码就像下,在Person中重载

namespace ContainerAndOperator
{
    class Program
    {
        static void Main(string[] args)
        {
            ContainerClass con = new ContainerClass();
            con[0] = new Person("homer", "11", 11);
            con[1] = new Person("homer1", "12", 12);
            con[2] = new Person("homer2", "13", 13);
            Console.WriteLine(con[2].name);
            foreach(Person s in con)
            {
                Console.WriteLine(s.name);
            }
            Console.WriteLine("*******************************");
            Person p3 = con[1] con[2];
            Console.WriteLine(p3.name);
            Console.WriteLine(con[1] - con[2]);
            Console.ReadLine();
        }
    }
}

      实施方案:
        1:能够如此写if(true==条件卡塔 尔(英语:State of Qatar),假使您写成了if(true=条件),编写翻译器会报错,因为true是不可能充任左值的。
        2:固然唯有一个规格,就直接if(条件),把==true给省略就能够,假若是多规格就按议程一来实践。

     /// <summary>
        /// 重载 号
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <returns>返回一个Person类型</returns>
        public static Person operator (Person p1,Person p2)
        {
            //将两个相加的Person类型分别让他们的
            //名字和年龄相加后的值赋值给被返回的Person类型
            Person p3 = new Person(p1.Name   p2.Name, p1.Age   p2.Age);
            return p3;
        }

因为有的时候我们或然须求对七个类进行对照,已成功部分一定的意义,不过,原生的操作符不帮忙的景观下,大家就可以重载操作符。

           说明:1:if(条件=true)这种程序当然并非技士想那要写,只是有时会少写二个罢了。

下一场我们就足以在Main中来相加八个Person类型了

                    2:if(条件=true),编写翻译器并不会报错,有园友说会出提醒警告,这里大家能够友善取证下。

看图

      第四:对于操作符的重载难点。比方大家想重载“==”,代码如下:八个对象相等的正规化正是属性sName相等,程序中意气风发上来就径直p.sName,未有伪造到p对象是或不是为null,这种也是编译器不也许在编写翻译时期剖断的。这种代码也独有在程序调节和测量试验时才相比易于察觉,借使您在前后相继中推断那一个自定义类是或不是为空:if(null==自定义类),大家从程序上来看这里都以不会出难题的,不过在等号重载中尚无看清指标的平价,那对BUG的各种核查也是生龙活虎对后生可畏辛苦的。

图片 2

              表明:这里重载了等号和不等号,这里并非多余的,而是必得,因为它们必需成对现身。

那般就水到渠成了

/// <summary>
    /// 自定义测量检验类
    /// </summary>
    public class a
    {
        public string sName
        {
            get;
            set;
        }
        public a(string _sName)
        {
            this.sName = _sName;
        }
        /// <summary>
        /// 重载==操作符
        /// </summary>
        /// <param name="p"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool  operator ==(a p, a b)
        {
            if (p.sName == b.sName)
            { return true; }
            else
            { return false; }
        }
        /// <summary>
        /// 重载!=操作符
        /// </summary>
        /// <param name="p"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool  operator !=(a p, a b)
        {
            return !Object.Equals(p, b);
           
        }

下一场此外的比如

    }

 

 

而关键点就在于风姿洒脱旦你要重载操作符就一定要格式如下

       第五:对于数据格式调换。拿字符串转换来数字来讲,比较多相恋的人赏识一贯int.Parse(要改变的字符串),假诺那些字符串是你指望的数字字符串这没难点,假如字符中为空,可能是积攒的中文或然其余非数字字符串,那也是更改退步,其实我们大可利用int.TryParse方法来解决,不成功还会有叁个默值,最少无法暂停程序的周转。

 

       笔者大致总括了多少个,大家看还也许有十分的少附近的不太好的习贯吗?

白话:public static 重回类型 operator被重载的操作符(本类型,要与之操作的档期的顺序)

  

正文:public static Person operator (Person p1,Person p2)   => 意思为:作者要让四个Person类型相加,然后回来贰个Person类型

依然你能够把再次来到类型改为int,然后五个Person类型相加后,你回来叁个int类型的多少回去

譬如说重回  p1.Age p2.Age  那样,在将多个Person类型相加之后,将收获二个int类型的数额,其值就是相加的多少个Person类型的Age值的相加值

 

还应该有个要留神的是,

如若你重载了 == 操作符,就非得要重载 != 因为它们是成对,还会有任何成对运算符

同有时常间重载了 == 后,还相应重载 Equals,以至GetHashCode

 

===========================================================================================================

 

上面再说说转换操作符

要么说下边包车型地铁特别Person吧

比方,作者非要让

Person p=30;

好端端情形下,是不只怕的,但假设自己那样在Person中写就行了

 public static implicit operator Person(int age)
        {
            return new Person(age);
        }

格式的话,正是长久死的,implicit关键字,假设没记错的话就是代表可以隐式调换

还应该有个展现调换的,作者忘了,不佳意思,懒得查资料了

那大器晚成段代码的意思便是

自身要让叁个Person类型的数据,能够给它三个int类型的值

例如

图片 3

 

=============================================================================================

后记:写得比非常少,只拣了多个例子去随意说了下,其实本身深感就那多少个例子就够了

别的的和睦多品尝,语法格式都以定点死了的,怎么写就看自个儿的观念有多么驰骋驰骋了

好了,最终我们来接受刚才说的东西,去解决一下上边这道题

图片 4

怎么让 

a==1 && a==2 && a==3 =true

如何做啊,看我们来调皮一下啊

 

第后生可畏,大家不管a是何许项目,反正不太只怕是int类型,因为不管原始a等于多少,上述表明式就像是都不为true

那么大家精诚团结来建个系列为Rational

咱俩要做的就风姿浪漫件事

为Rational重载 == 操作符

让它不管与什么int类型的数字相比较都回去true  (够调皮吧)

看代码吧:

class Rational
    {
        public int Val { get; set; } = 0;

        public Rational()
        {

        }

        public Rational(int val)
        {
            this.Val = val;
        }

        /// <summary>
        /// 我们重载了==操作符
        /// </summary>
        /// <param name="r"></param>
        /// <param name="val"></param>
        /// <returns></returns>
        public static bool operator==(Rational r,int val)
        {
            //只返回一个true是为了让所有与Rational类型相比对的int类型
            //都返回true
            //因为重载了==,所以必须重载!=
            //其实还应该重载Equals,以及GetHashCode
            //因为它们都是判断相等的类型

            return true;
        }

        public static bool operator !=(Rational r, int val)
        {
            return true;
        }

    }

 

然后在Main中间试验试吧

 static void Main(string[] args)
        {
            Rational a = new Rational();
            bool result = a == 1 && a == 2 && a == 3;
            Console.WriteLine(result);
            Console.ReadKey();
        }

你会意识,为true,是啊

 

本文由pc28.am发布于计算机编程,转载请注明出处:粗略的操作符重载,关于操作符重载与转移

上一篇:路由原理,mvc西路由的映射和兑现IHttpHandler挂载 下一篇:没有了
猜你喜欢
热门排行
精彩图文