C#如何提高代码质量(一)

 

代码部分                                
    1.正确操作字符串                            
        尽量少装箱                        
            String str1 = "str2"+9.ToString();                    
        避免分配额外的内存空间                        
            StringBuilder                    
    2.使用默认转型方法                            
        使用类型的转换运算符                        
            编译器直接支持的数据类型,即直接映射到FCL中的类型。包括sbyte、byteshort、ushort、int、uint、long、ulong、charfloatdouble、bool、decimal、object、string                    
        使用类型内置的方法                        
            Parse,TryParse,ToString,ToDouble,ToDateTIme                    
        使用帮助类提供的方法                        
            System.Convert和System.BitConverter                    
        使用CLR支持的转型                        
            基类和子类的相互转换                    
    3.区别对待强制转型与as和is                            
        强转 继承public static explicit operator 类名(待转换类名)                        
        as 不抛出异常                        
    4.TryParse比Parse好                            
    5.使用int?来确保值类型也可以为null                            
    6.区别readonly和const的使用方法                            
        const是编译器常量(自带static),readonly是一个运行时常量                        
        const只能修饰基元类型,枚举或者字符串,readonly没有限制                        
        "readonly第一次被赋值后不可以改变
            1.对于值类型,值本身不可改变
             2.对于引用类型,引用本身(指针)不可改变"                        
    7.将0值作为枚举的默认值                            
        编译器会从0值开始计数                        
    8.习惯重载运算符                            
    9.创建对象时需要考虑是否实现比较器                            
        实现Icompareable或Icomparer<T>                        
    10.区别对待==和Equals                            
        "对于值类型,如果类型的值相等,就应该返回True对于应用类型,如果类型指向同一个对象,则返回True"                        
    11.为类型输出格式化字符串                            
    12.用dynamic简化反射实现                            
        dynamic 类 x = new 类();                        
    13.元素数量可变的情况下不应使用数组                            
        一维数组:newarr,ldelemldelmea, stelem                        
    14.使用List<T>而不是用ArrayList                            
        List<T>    SortedList<T>    ConcurrentBag<T>                
        Dictionary<Tkey,Tvalue>    StortedDictionary<Tkey,Tvalue>    ConcurrentDictionary<Tkey,Tvalue>                
        HashSet<T>    StortedSet<T>                    
        Queue<T>        ConcurrentQueue<T>                
        Stack<T>        ConcurrentStack<T>                
    15.确保集合的线程安全                            
        需要使用lock进行锁定                        
    16.迭代器不要有可写属性                            
    17.谨慎集合中的可写属性                            
    18.使用匿名类型存储LINQ查询结果                            
        var personWithCompanyList = from person in personList join company in companyList on person.CompanyID qeuals company.ComanyID select new {PersonName=person.Name, CompanyName = company.Name}  
    19.查询中受用Lambda表达式                            
    20.延迟求值和主动求职的区别                            
         from c in list where c>5 select c                        延迟求值                
        (from c in list where c>5 select c).ToList<int>();        主动求值                
    21.区别Linq查询中的Ienumerable<T>和Iqueryable<T>                            
        IEnumerable<T> 本地数据源   基本变量                        
        IQueryable<T>  远程数据源      数据库        不能直接使用自定义方法                
    22.使用LINQ取代集合中的比较器和迭代器                            
    23.使用Linq时注意不必要的迭代                            
        (from c in list select c).Take(2).ToList()               只迭代两次                        
        (from c in list where c.name=="Mike" select c).First()   拿到就返回                        
泛型/委托和事件                                
    24.尽可能使用泛型                            
    25.避免在泛型类型中声明静态成员                            
        泛型中数据类型不一致,则静态成员不共享                        
    26.为泛型参数设定约束                            
        public int Compare<T>(T t1, T t2) where T:Salary                        
        此时T变为了Salary类,就拥有了其相关属性                        
    27.使用default为泛型类型变量指定初始值                            
    28.使用FCL中的委托声明                            
        Action,Func,Predicate                        
    29.使用Lambda进行委托                            
        Func<int, int, int> add = delegate(int I, int j){return i+j;};                        
        Action<string> print = delegate(string msg){Console.WriteLine(msg);};                        
        print(add(1,2).ToString());                        
        Func<int, int, int> add =(I, j)=>{return i+j;};                        
        Action<string> print = (msg)=>{Console.WriteLine(msg);};                        
    30.小心闭包中的陷阱                            
        触发方法时才会调用方法                        
    31.使用event关键字为委托施加保护                            
    32.标准的事件模型                            
        public delegae void EventHandler(object sender, EventArgs e);                        
        委托类型的名称以EventHandler结束                        
        委托原型返回值为void                        
        委托原型有两个参数:sender表示事件触发者,e表示事件参数                        
        事件参数的名称以EventArgs结束                        
    33.为泛型类型参数指定逆变                            
资源管理和序列化                                
    1.显示释放资源需集成接口Idisposable                            
    2.必要时应将不再使用的对象引用赋值为null                            
        静态变量不会主动Disposable                        
    3.为无用字段标注不可序列化                            
     [Serializable]           序列化                    
     [NonSerialized]          不序列化                    
     [fidle:NonSerialized]    事件非序列化                    
     public class BinarySerializer{
         //将类型序列化为字符串
         public static string Serialize<T>(T t){
             using(MemoryStream stream = new MemoryStream()){
                 BinaryFormatter formatter = new BinaryFormatter();
                 formatter.Serialize(stream, t);
                 return System.Text.Encoding.UTF8.GetString(stream.ToArray());
             }
         }
         // 将类型序列化为文件
         public static void SerializeToFile<T>(T t, string path, string fullName){
             if(!Directory.Exists(path)){Directory.CreateDirectory(path);}
             string fullPath = $""{pth}\{fullName}"";
             using(FileStream stream = new FileStream(fullPath, FileMode.OpenOrCreate))
             {
                     BinaryFormatter formatter = new BinaryFormatter();
                     formatter.Serialize(stream, t);
                     stream.Flush();
                 }
            }
            //将字符串反序列化为类型
             public static TResult Deserialize<TResult>(string s) where TResult:class{
                 byte[] bs = System.TextEncoding.UTF8.GetBytes(s);
                 using (MemoryStream stream = new MemoryStream(bs)){
                 BinaryFormatter formatter = new BinaryFormatter();
                 return formatter.Deserialize(stream) as TResult;
             }
         }
        //将文件反序列化为类型
        public static TResult DeserializeFromFile<TResult>(string path) where TResult:class{
            using(FileStream stream = new FileStream(path, FileMode.Open)){
                BinaryFormatter formatter = new BinaryFormatter();
                return formatter.Deserialize(stream) as TResult;
            }
        }
    }                       
    4.利用定制特性减少可序列化的字段                            
        OnDeserializedAttribute 指定对象反序列化后立即调用此方法                        
        OnDeserializeingAttribute 指定在反序列化时调用此方法                        
        OnSerializedAttribute      指定在序列化该对象后是否调用该方法                        
        OnSerializingAttribute    指定在对象序列化前调用此方法                    
    5.使用集成Iserializable接口更灵活的控制序列化过程                            

 

posted @ 2022-12-17 14:03  摧残一生  阅读(84)  评论(0编辑  收藏  举报