重載運算子

來源:互聯網
上載者:User

標籤:des   style   class   blog   code   ext   

重載運算子在實際的工作中很用到,但如果某些自訂類型通過簡短几行代碼重載一些常用的運算子(如:+-*/),就能讓編程工作帶來方便;重載運算子就是告訴編譯器+-*/等運算子對於自訂類型進行什麼樣的操作,在代碼中需要注意幾點。

一、儘可能的不要改變運算子本身的含義

二、所有的運算子多載都必須聲明為public和static

三、不同於擴充方法,所重載的方法必須是在被重載的類型內部,且用關鍵 operator

C#中的兩個字串相加,實際上是串連兩個字串,假如有兩個EmployeeDetail類型相加得到一個EmployeeCollection集合,如:

EmployeeDetail a,b;

....

EmployeeCollection collection = a+b;

當編譯器遇到上面的代碼時就會自動調用EmployeeDetail類上標有operator +的靜態方法,並將兩個運算元a和b作為參數傳遞給對於的方法,該方法需要方法一個值賦給collection,假設EmployeeDetail類有三個屬性分別是FirstName,MiddleName,LastName,還重寫了ToString方法返回一個串連這三個名稱的字串,代碼如:

  [Serializable]    public class EmployeeDetail    {        public string FirstName { get; set; }        public string MiddleName { get; set; }        public string LastName { set;get; }        public override string ToString()        {            return string.Format("{0}{1}{2}{3}{4}", FirstName, string.IsNullOrWhiteSpace(MiddleName) ? null : "."                , MiddleName                , string.IsNullOrWhiteSpace(LastName) ? null : ".",                LastName).Trim();        }    }

 

下面的代碼為“+”運算子提供支援的運算子多載:

 public static EmployeeCollection operator +(EmployeeDetail a, EmployeeDetail b)        {            return new EmployeeCollection() { a, b };        }

OK,給EmployeeDetail類加上這樣的一個方法之後,我們就可以像下面那個寫代碼了:

EmployeeCollection collection = new EmployeeDetail(){FirstName="Jackson",LastName="Bruce"}  + new EmployeeDetail(){FirstName="Michael",LastName="Jackson"} ;

但是這樣還不夠完美,假設a,b,c都是EmployeeDetail類型,下面的代碼會拋出一個編譯錯誤:

EmployeeCollection collection = a + b + c;

為什麼編譯不通過呢?大家都知道除了賦值運算子外運算式是從左至右執行的,a+b返回的是EmployeeCollection類型,EmployeeCollection類型並沒有重載“+”運算子,編譯器不知道要執行什麼操作,所以我們還有下面的兩個方法:

        public static EmployeeCollection operator +(EmployeeCollection collection, EmployeeDetail a)        {            collection.Add(a);            return collection;        }        public static EmployeeCollection operator +(EmployeeDetail a, EmployeeCollection collection)        {            return collection + a;        }

 

 

這看起來似乎已經很完美了,但我們還可以做得更好一些,比如要將字串“Jackson.Bruce”直接隱式轉換為EmployeeDetail類型,也就是說可以將“Jackson.Bruce"這種格式的字串直接賦給EmployeeDetail類型的對象,如:EmployeeDetail employee= “Jackson.Bruce",那麼就需要重載隱式類型轉換運算子了,代碼如下:

/// <summary>        /// 隱式類型轉換        /// </summary>        /// <param name="name"></param>        /// <returns></returns>        public static implicit operator EmployeeDetail(string name)        {

       /// 其實在這裡可以寫一個Regex檢查name的字串格式是否合法,如果不合法就拋出異常
       /// string[] arr; return string.IsNullOrWhiteSpace(name) ? null : new EmployeeDetail() { FirstName = (arr = name.Trim().Split(‘.‘))[0] , LastName = arr.Length > 1 ? arr[arr.Length > 2 ? 2 : 1] : null, MiddleName = arr.Length > 2 ? arr[1] : null }; } public static EmployeeCollection operator +(EmployeeDetail a, string b) { return new EmployeeCollection() { a, b }; }

 

 

看到這裡您是不是迫不及待地想試試看,OK寫個控制台程式來測試一下:

        static void Main(string[] args)        {            EmployeeDetail employee = "Jackson.Bruce";            Console.WriteLine("FirstName={0},MiddleNam={1},LastName={2}", employee.FirstName, employee.MiddleName, employee.LastName);            Console.WriteLine("toString={0}", employee);            Console.WriteLine();            EmployeeCollection collection = "Michael.Jackson" + employee;            collection += "Bruce.Lee";            foreach (var e in collection)            {                Console.WriteLine(e);            }            Console.WriteLine();            collection -= employee;            foreach (var e in collection)            {                Console.WriteLine(e);            }            Console.WriteLine("===end===");            Console.Read();        }

 

 

運行結果

 

 

全部代碼,裡面還包含其他運算子的重載,這裡就不再介紹了,趕緊試試吧:

 

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace 重載運算子{    [Serializable]    public class EmployeeDetail    {        public string FirstName { get; set; }        public string MiddleName { get; set; }        public string LastName { set;get; }        public static EmployeeCollection operator +(EmployeeDetail a, EmployeeDetail b)        {            return new EmployeeCollection() { a, b };        }                     public static EmployeeCollection operator +(EmployeeCollection collection, EmployeeDetail a)        {            collection.Add(a);            return collection;        }        public static EmployeeCollection operator +(EmployeeDetail a, EmployeeCollection collection)        {            return collection + a;        }        /// <summary>        /// 隱式類型轉換        /// </summary>        /// <param name="name"></param>        /// <returns></returns>        public static implicit operator EmployeeDetail(string name)        {            string[] arr;            return string.IsNullOrWhiteSpace(name) ? null :                new EmployeeDetail()                {                    FirstName = (arr = name.Trim().Split(‘.‘))[0]                    ,                    LastName = arr.Length > 1 ? arr[arr.Length > 2 ? 2 : 1] : null,                    MiddleName = arr.Length > 2 ? arr[1] : null                };        }        public static EmployeeCollection operator +(EmployeeDetail a, string b)        {            return new EmployeeCollection() { a, b };        }        public override string ToString()        {            return string.Format("{0}{1}{2}{3}{4}", FirstName, string.IsNullOrWhiteSpace(MiddleName) ? null : "."                , MiddleName                , string.IsNullOrWhiteSpace(LastName) ? null : ".",                LastName).Trim();        }    }    public class EmployeeCollection : List<EmployeeDetail>    {        public static EmployeeCollection operator +(EmployeeCollection a, string b)        {            a.Add(b);            return a;        }        public static EmployeeCollection operator +(string b, EmployeeCollection a)        {            return a + b;        }        public static EmployeeCollection operator -(EmployeeCollection a,  EmployeeDetail b)        {            a.Remove(b);            return a;        }    }      class Program    {        static void Main(string[] args)        {            EmployeeDetail employee = "Jackson.Bruce";            Console.WriteLine("FirstName={0},MiddleNam={1},LastName={2}", employee.FirstName, employee.MiddleName, employee.LastName);            Console.WriteLine("toString={0}", employee);            Console.WriteLine();            EmployeeCollection collection = "Michael.Jackson" + employee;            collection += "Bruce.Lee";            foreach (var e in collection)            {                Console.WriteLine(e);            }            Console.WriteLine();            collection -= employee;            foreach (var e in collection)            {                Console.WriteLine(e);            }            Console.WriteLine("===end===");            Console.Read();        }    }}

 

 

 

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.