国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

編寫(xiě)高質(zhì)量代碼改善C#程序的157個(gè)建議[為類(lèi)型輸出格式化字符串、實(shí)現(xiàn)淺拷貝和深拷貝、用dynamic來(lái)優(yōu)化反射]

2019-11-17 03:15:30
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

編寫(xiě)高質(zhì)量代碼改善C#程序的157個(gè)建議[為類(lèi)型輸出格式化字符串、實(shí)現(xiàn)淺拷貝和深拷貝、用dynamic來(lái)優(yōu)化反射]

前言

  本文已更新至http://m.survivalescaperooms.com/aehyok/p/3624579.html。本文主要學(xué)習(xí)記錄以下內(nèi)容:

  建議13、為類(lèi)型輸出格式化字符串

  建議14、正確實(shí)現(xiàn)淺拷貝和深拷貝

  建議15、使用dynamic來(lái)簡(jiǎn)化反射實(shí)現(xiàn)

建議13、為類(lèi)型輸出格式化字符串

  有兩種方法可以為類(lèi)型提供格式化的字符串輸出。

  一種是意識(shí)到類(lèi)型會(huì)產(chǎn)生格式化字符串輸出,于是讓類(lèi)型繼承接口IFormattable。這對(duì)類(lèi)型來(lái)說(shuō),是一種主動(dòng)實(shí)現(xiàn)的方式,要求開(kāi)發(fā)者可以預(yù)見(jiàn)類(lèi)型在格式化方面的要求。

  更多的時(shí)候,類(lèi)型的使用者需為類(lèi)型自定義格式化器,這就是第二種方法,也是最靈活多變的方法,可以根據(jù)需求的變化為類(lèi)型提供多個(gè)格式化器。

  下面我們就來(lái)看一下這兩種方式的實(shí)現(xiàn)。

  最簡(jiǎn)單的字符串輸出是為類(lèi)型重寫(xiě)ToString()方法,如果沒(méi)有為類(lèi)型重寫(xiě)該方法,默認(rèn)會(huì)調(diào)用Ojbect的ToString方法,它會(huì)返回當(dāng)前類(lèi)型的類(lèi)型名稱(chēng)。但即使是重寫(xiě)了ToString()方法,提供的字符串輸出也是非常單一的,而通過(guò)實(shí)現(xiàn)IFormattable接口的ToString()方法,可以讓類(lèi)型根據(jù)用戶(hù)的輸入而格式化輸出。

下面我們來(lái)看一個(gè)簡(jiǎn)單的小例子:

    public class Person:IFormattable    {        public string IDCode { get; set; }        public string FirstName { get; set; }        public string LastName { get; set; }        /// <summary>        /// 實(shí)現(xiàn)接口Iformattable的方法ToString        /// </summary>        /// <param name="format"></param>        /// <param name="format

調(diào)用代碼如下所示:

        static void Main(string[] args)        {            Person person = new Person() { FirstName="Kris",LastName="aehyok"};            Console.WriteLine(person);            Console.WriteLine(person.ToString("Ch",null));            Console.WriteLine(person.ToString("Eg", null));            Console.ReadLine();        }

調(diào)用執(zhí)行結(jié)果如下:

  下面我們來(lái)繼續(xù)介紹第二實(shí)現(xiàn)方式——格式化器。如果類(lèi)型本身沒(méi)有提供格式化的功能,那么格式化器就可以派上用場(chǎng)了。格式化器的好處就是可以根據(jù)需求的變化,隨時(shí)增加或者修改它。

  接下來(lái)我們繼續(xù)來(lái)看另外的一個(gè)小例子:

首先定義一個(gè)實(shí)體類(lèi)Person:

    public class Person    {        public string IDCode { get; set; }        public string FirstName { get; set; }        public string LastName { get; set; }    }

一個(gè)典型的格式化器應(yīng)該繼承IFormatProvider和ICustomerFormatter,看代碼:

    public class PersonFomatter:IFormatProvider,ICustomFormatter    {        #region IFormatProvider成員        public object GetFormat(Type formatType)        {            if (formatType == typeof(ICustomFormatter))            {                return this;            }            else            {                return null;            }        }        #endregion        #region ICustomFormatter成員        public string Format(string format, object arg, IFormatProvider formatProvider)        {            Person person = arg as Person;            if (person == null)            {                return string.Empty;            }            switch (format)            {                 case"Ch":                    return string.Format("{0} {1}",person.LastName,person.FirstName);                case"":                    return string.Format("{0} {1}",person.FirstName,person.LastName);                case"CHM":                    return string.Format("{0} {1}:{2}", person.LastName, person.FirstName, person.IDCode);                default:                    return string.Format("{0} {1}", person.LastName, person.FirstName);            }        }        #endregion    }

調(diào)用代碼如下:

    class Program    {        static void Main(string[] args)        {            Person person = new Person() { FirstName="Kris", LastName="aehyok", IDCode="ID000001"};            Console.WriteLine(person.ToString());            PersonFomatter pFomatter = new PersonFomatter();            Console.WriteLine(pFomatter.Format("Ch", person, null));            Console.WriteLine(pFomatter.Format("Eg", person, null));            Console.WriteLine(pFomatter.Format("CHM", person, null));            Console.ReadLine();        }    }

調(diào)用執(zhí)行結(jié)果如下:

其實(shí)還有另外一種變通的形式,就是將這兩種方式合并一起使用的過(guò)程,下面來(lái)看一下具體的實(shí)現(xiàn)代碼:

public class Person:IFormattable    {        public string IDCode { get; set; }        public string FirstName { get; set; }        public string LastName { get; set; }                /// <summary>        /// 實(shí)現(xiàn)接口Iformattable的方法ToString        /// </summary>        /// <param name="format"></param>        /// <param name="formatProvider"></param>        /// <returns></returns>        public string ToString(string format, IFormatProvider formatProvider)        {            switch (format)            {                 case"Ch":                    return this.ToString();                case"Eg":                    return string.Format("{0}{1}", this.FirstName, this.LastName);                default:                    //return this.ToString();                    ICustomFormatter customerFormatter = formatProvider as ICustomFormatter;                    if (formatProvider == null)                    {                        return this.ToString();                    }                    return customerFormatter.Format(format, this, null);            }        }        ///重寫(xiě)Object的方法ToString()        public override string ToString()        {            return string.Format("{0}{1}",this.LastName,this.FirstName);        }    }

PersonFomatter自定義格式化器的代碼并沒(méi)有發(fā)生任何的改變。調(diào)用代碼如下:

        static void Main(string[] args)        {            Person person = new Person() { FirstName="Kris", LastName="aehyok", IDCode="ID000001"};            Console.WriteLine(person.ToString());            PersonFomatter pFomatter = new PersonFomatter();            Console.WriteLine(pFomatter.Format("Ch", person, null));            Console.WriteLine(pFomatter.Format("Eg", person, null));            Console.WriteLine(pFomatter.Format("CHM", person, null));            Console.WriteLine(person.ToString("Ch",pFomatter));            Console.WriteLine(person.ToString("Eg", pFomatter));            Console.WriteLine(person.ToString("CHM", pFomatter));            Console.ReadLine();        }

調(diào)用執(zhí)行結(jié)果如下所示:

建議14、正確實(shí)現(xiàn)淺拷貝和深拷貝

為對(duì)象創(chuàng)建副本的技術(shù)成為拷貝(也叫克隆)。我們將拷貝分為淺拷貝和深拷貝。

淺拷貝 將對(duì)象中的所有字段復(fù)制到新的對(duì)象(副本)中。其中,值類(lèi)型字段的值被復(fù)制到副本中后,在副本中的修改不會(huì)影響到源對(duì)象對(duì)應(yīng)的值。而引用類(lèi)型的字段被復(fù)制到副本中的是引用類(lèi)型的引用,而不是引用的對(duì)象,在副本中對(duì)引用類(lèi)型的字段值做修改會(huì)影響到源對(duì)象本身。

深拷貝同樣,將對(duì)象中的所有字段復(fù)制到新的對(duì)象中。不過(guò)無(wú)論是對(duì)象的值類(lèi)型字段,還是引用類(lèi)型字段,都會(huì)被重新創(chuàng)建并賦值,對(duì)于副本的修改,不會(huì)影響到源對(duì)象本身。

無(wú)論是淺拷貝還是深拷貝,微軟都建議用類(lèi)型繼承ICloneable接口的方式明確告訴調(diào)用者:該類(lèi)型可以被拷貝。當(dāng)然,ICloneable接口只提供了一個(gè)聲明為Clone的方法,我們可根據(jù)需求在Clone方法內(nèi)實(shí)現(xiàn)淺拷貝或深拷貝。一個(gè)簡(jiǎn)答的淺拷貝的實(shí)現(xiàn)代碼如下所示:

首先定義實(shí)體類(lèi):

    public class Employee:ICloneable    {        public string IDCode { get; set; }        public int Age { get; set; }        public Department Department { get; set; }        #region OCloneable成員        public object Clone()        {            return this.MemberwiseClone();        }        #endregion    }    public class Department    {        public string Name{get;set;}        public override string  ToString()        {              return this.Name;        }    }

然后進(jìn)行調(diào)用代碼如下:

        static void Main(string[] args)        {            Employee Niki = new Employee()            {                IDCode = "IDaehyok",                Age = 25,                Department = new Department() { Name="Depart1" }            };            Employee Kris = Niki.Clone() as Employee;            Console.WriteLine(string.Format("IDCode:{0}/tAge:{1}/tDepartment:{2}", Kris.IDCode, Kris.Age, Kris.Department));            ///開(kāi)始改變Niki的值
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 朔州市| 阿坝县| 江西省| 吉水县| 纳雍县| 尼玛县| 盐边县| 平原县| 罗甸县| 资阳市| 仙居县| 大厂| 莱州市| 南京市| 大姚县| 河间市| 安仁县| 容城县| 万盛区| 保定市| 鸡西市| 马鞍山市| 合山市| 湛江市| 开平市| 乌兰察布市| 莱西市| 宁国市| 梨树县| 古交市| 桐庐县| 芒康县| 义乌市| 荃湾区| 汝城县| 得荣县| 克拉玛依市| 缙云县| 津南区| 弥勒县| 项城市|