zoukankan      html  css  js  c++  java
  • 读改善c#代码157个建议:建议13~15

    目录:

    • 建议13:为类型输出格式化字符串
    • 建议14:正确实现浅拷贝和深拷贝
    • 建议15:使用dynamic来简化反射实现

    一、建议13:为类型输出格式化字符串

    有些类型需要我们根据业务需求提供字符串的格式化输出。

    1、我们明确知道业务需求什么样的输出格式,也就是类型主动格式化输出。

    可以重写Object.ToString()方法,也可以继承IFormattable接口实现ToString,对字符串进行输出。

    class Person :IFormattable
        {
            public string IDCode { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
    
            public string ToString(string format, IFormatProvider formatProvider)
            {
                switch (format)
                {
                    case "CH": return this.ToString();
                    case "US": return string.Format("{0}{1}", LastName, FirstName);
                    default: return this.ToString();                
                }
            }
    
            public override string ToString()
            {
                return string.Format("{0}{1}", FirstName,LastName);
            }
        }

    客户端:

     Person p = new Person() { IDCode = "No1", FirstName = "Sun", LastName = "N" };
    
                Console.WriteLine(p);
    
                Console.WriteLine(p.ToString("CH", null));
                Console.WriteLine(p.ToString("US", null));
    
                Console.ReadKey();

    实例:记得之前做过一个API展示:API的Name是英文名,还有一个字段描述。现在我想看到API.ToString()展示的格式是:英文名:描述。就可以稍微重写ToString()进行格式化输出。

             public override string ToString()
            {
                if (!string.IsNullOrEmpty(this.ApiName) && !string.IsNullOrEmpty(this.Description))            
                    return string.Format("{0}:{1}", this.ApiName, this.Description);
                
                return string.Empty;
            }

    2、使用格式化器进行格式化输出

    如果类不能提供字符串的格式化输出,我们就可以使用格式化器,好处是我们可以根据需求修改格式化器的输出。

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

    格式化器:典型的格式化器应该继承IFormatProvider(继承这个接口有什么作用?), ICustomFormatter

    class PersonFormatter : IFormatProvider, ICustomFormatter
        {
            public object GetFormat(Type formatType)
            {
                if (formatType == typeof(ICustomFormatter))
                    return this;
                else
                    return null;
            }
    
            public string Format(string format, object arg, IFormatProvider formatProvider=null)
            {
                Person p = arg as Person;
                if (p == null)
                    return string.Empty;
    
                switch (format)
                {
                    case "CH": return string.Format("{0}{1}", p.FirstName, p.LastName);
                    case "US": return string.Format("{0}{1}", p.LastName, p.FirstName);
                    default: return string.Format("{0}{1}", p.FirstName, p.LastName);
                }
            }
        }

    客户端:

     Person p = new Person() { IDCode = "No1", FirstName = "Sun", LastName = "N" };
    
                //不重写ToString,返回类型名称
                Console.WriteLine(p.ToString());
    
                PersonFormatter pf = new PersonFormatter();
    
                Console.WriteLine(pf.Format("CH", p));
    
                Console.WriteLine(pf.Format("US", p));
    
                Console.WriteLine(pf.Format("", p));
    
                Console.ReadKey();

    运行:

    二、建议14:正确实现浅拷贝和深拷贝

    建议继承ICloneable接口。浅拷贝,拷贝的对象中的引用类型的值的改变会互相影响。而深拷贝就是为了解决浅拷贝的这个问题。

    下面是继承了ICloneable接口,并实现了浅拷贝和深拷贝的类。

    这里的深拷贝的实现方法是使用序列化格式化器:BinaryFormatter,将类成员信息序列化成二进制流,然后反序列化成当前类。这里使用序列化所以类需要加上特性[Serializable],以示此类具有序列化、反序列化能力。

    [Serializable]
        internal class Product:ICloneable
        {
            public string Name { get; set; }
    
            public int Age { get; set; }
    
            public NumberFlag Number { get; set; }      
            
         //浅拷贝
    public object Clone() { return this.MemberwiseClone(); }      //深拷贝 public Product DeepClone() { using (System.IO.Stream ms = new System.IO.MemoryStream()) { System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); formatter.Context = new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.Clone); formatter.Serialize(ms, this); ms.Position = 0; return formatter.Deserialize(ms) as Product; } } } [Serializable] internal class NumberFlag { public string Num { get; set; } }

    客户端:浅拷贝—引用类型值得改变会相互影响。

    Product p1 = new Product()
                {
                    Name = "1",
                    Age = 1,
                    Number = new NumberFlag() { Num="01"}
                };                      
    
                var p2 = p1.Clone() as Product;
    
                if (p2 != null)
                {
    
                    p2.Number.Num = "22";
    
                    Console.WriteLine("p1 Number:{0}.",p1.Number.Num);
    
                    Console.WriteLine("p2 Number:{0}.",p2.Number.Num);
    
                    Console.ReadKey();
                }

    运行:

    客户端:深拷贝—不会有浅拷贝的那种情况。

    Product p1 = new Product()
                {
                    Name = "1",
                    Age = 1,
                    Number = new NumberFlag() { Num="01"}
                };                      
    
                var p2 = p1.DeepClone();
    
                if (p2 != null)
                {
    
                    p2.Number.Num = "22";
    
                    Console.WriteLine("p1 Number:{0}.",p1.Number.Num);
    
                    Console.WriteLine("p2 Number:{0}.",p2.Number.Num);
    
                    Console.ReadKey();
                }

    运行:

     三、建议15:使用dynamic来简化反射实现

    这个建议~虽然实例中性能比反射好,但是编译期间跳过验证。运行时才进行类型安全检查。待比较后,才能确定是否使用反射还是dynamic.

  • 相关阅读:
    AcWing 1027. 方格取数 dp
    AcWing 1014. 登山 dp
    acwing 482. 合唱队形 dp
    LeetCode 1463. 摘樱桃II dp
    LeetCode 100. 相同的树 树的遍历
    LeetCode 336. 回文对 哈希
    LeetCode 815. 公交路线 最短路 哈希
    算法问题实战策略 DARPA大挑战 二分
    算法问题实战策略 LUNCHBOX 贪心
    AcWing 1100. 抓住那头牛 BFS
  • 原文地址:https://www.cnblogs.com/sunchong/p/4663276.html
Copyright © 2011-2022 走看看