在线设计网站海报,界面设计师培训,教育网站制作哪专业,网站建设水平如何评价如有不理解#xff0c;请留言#xff0c;开始!1. 正确操作字符串拼接字符串一定要考虑使用 StringBuilder ,默认长度为16,实际看情况设置。StringBuilder本质#xff1a; 是以非托管方式分配内存。同时StringFormat方法 内部也是使用StringBuilder进行字符串格式化。2. 使用… 如有不理解请留言开始!1. 正确操作字符串拼接字符串一定要考虑使用 StringBuilder ,默认长度为16,实际看情况设置。StringBuilder本质 是以非托管方式分配内存。同时StringFormat方法 内部也是使用StringBuilder进行字符串格式化。2. 使用默认转型方法类型的转换运算符 :每个类型内部都有一个方法(运算符),分为隐式转换和显示转换。自己实现隐式转换puclic static implicit operator Ip(string ip) { Ip iptempnew Ip(ip) return iptemp; }使用类型内置的Parse、TryParse、 ToString、ToDouble、 ToDateTime使用帮助类提供的方法 System.Convert类、 System.BitConverter类来进行类型的转换。使用CLR支持的类型父类和子类之间的转换。3. 区别对待强制转型与as和is为了编译更强壮的代码建议更常使用as和is什么时候使用as如果类型之间都上溯到了某个共同的基类那么根据此基类进行的转型即基类转型为子类本身应该使用as。子类与子类之间的转型则应该提供转换操作符以便进行强制转型。as操作符永远不会抛出异常如果类型不匹配被转换对象的运行时类型既不是所转换的目标类型也不是其派生类型或者转型的源对象为null那么转型之后的值也为null。什么时候使用isas操作符有一个问题即它不能操作基元类型。如果涉及基元类型的算法就需要通过is转型前的类型来进行判断以避免转型失败。4.TryParse比Parse好这个肯定好不说了。安全5.使用int?来确保值类型也可以为null基元类型为什么需要为null考虑两个场景数据库支持整数可为空数据在传输过程中存在丢失问题导致传过来的值为null写法 int?inull;语法T?是NullableT的简写两者可以相互转换。可以为null的类型表示其基础值类型正常范围内的值再加上一个null值。例如NullableInt32其值的范围为-2 147 483 6482 147 483 647再加上一个null值。经常和配合使用比如Copyint?i123; int ji??0;6.区别readonly和const的使用方法使用const的理由只有一个那就是效率。之所以说const变量的效率高是因为经过编译器编译后我们在代码中引用const变量的地方会用const变量所对应的实际值来代替。比如 const100, const和100被使用的时候是等价const自带static光圈。const和readonly的本质区别如下const是编译期常量readonly是运行期常量const只能修饰基元类型、枚举类型或字符串类型readonly没有限制。注意在构造方法内可以多次对readonly赋值。即在初始化的时候。7.将0值作为枚举的默认值允许使用的枚举类型有byte、sbyte、short、ushort、int、uint、long和ulong。应该始终将0值作为枚举类型的默认值。不过这样做不是因为允许使用的枚举类型在声明时的默认值是0值而是有工程上的意义。既然枚举类型从0开始这样可以避免一个星期多出来一个0值。8.避免给枚举类型的元素提供显式的值不要给枚举设定值。有时候有某些增加的需要会为枚举添加元素在这个时候就像我们为枚举增加元素ValueTemp一样极有可能会一不小心增加一个无效值。9.习惯重载运算符比如Salary familyIncomemikeIncomeroseIncome; 阅读一目了然。通过使用opera-tor关键字定义静态成员函数来重载运算符让开发人员可以像使用内置基元类型一样使用该类型。10.创建对象时需要考虑是否实现比较器有特殊需要比较的时候就考虑。集合排序比较通过linq 也可以解决。11.区别对待和Equals无论是操作符“”还是方法“Equals”都倾向于表达这样一个原则对于值类型如果类型的值相等就应该返回True。对于引用类型如果类型指向同一个对象则返回True。注意 由于操作符“”和“Equals”方法从语法实现上来说都可以被重载为表示“值相等性”和“引用相等性”。所以为了明确有一种方法肯定比较的是“引用相等性”FCL中提供了Object.ReferenceEquals方法。该方法比较的是两个示例是否是同一个示例。对于string这样一个特殊的引用类型微软觉得它的现实意义更接近于值类型所以在FCL中string的比较被重载为针对“类型的值”的比较而不是针对“引用本身”的比较。12.重写Equals时也要重写GetHashCode除非考虑到自定义类型会被用作基于散列的集合的键值否则不建议重写Equals方法因为这会带来一系列的问题。集合找到值的时候本质上是先去 查找HashCode,然后才查找该对象来比较Equals注意重写Equals方法的同时也应该实现一个类型安全的接口IEquatableT比如 class Person:IEquatable13.为类型输出格式化字符串有两种方法可以为类型提供格式化的字符串输出。一种是意识到类型会产生格式化字符串输出于是让类型继承接口IFormattable。这对类型来说是一种主动实现的方式要求开发者可以预见类型在格式化方面的要求。更多的时候类型的使用者需为类型自定义格式化器这就是第二种方法也是最灵活多变的方法可以根据需求的变化为类型提供多个格式化器。一个典型的格式化器应该继承接口IFormatProvider和ICustomFomatter14.正确实现浅拷贝和深拷贝浅拷贝 将对象中的所有字段复制到新的对象副本中。其中值类型字段的值被复制到副本中后在副本中的修改不会影响到源对象对应的值。而引用类型的字段被复制到副本中的是引用类型的引用而不是引用的对象在副本中对引用类型的字段值做修改会影响到源对象本身。深拷贝 同样将对象中的所有字段复制到新的对象中。不过无论是对象的值类型字段还是引用类型字段都会被重新创建并赋值对于副本的修改不会影响到源对象本身。无论是浅拷贝还是深拷贝微软都建议用类型继承IClone-able接口的方式明确告诉调用者该类型可以被拷贝。当然ICloneable接口只提供了一个声明为Clone的方法我们可以根据需求在Clone方法内实现浅拷贝或深拷贝。一个简单的浅拷贝的实现代码如下所示Copyclass Employee:ICloneable { public string IDCode {get;set;} public int Age {get;set; } public Department Department{get;set;} #region ICloneable成员 public object Clone() { return this.MemberwiseClone(); } #endregion}class Department{ public string Name {get;set;} public override string ToString() { return this.Name; }}注意到Employee的IDCode属性是string类型。理论上string类型是引用类型但是由于该引用类型的特殊性无论是实现还是语义Object.MemberwiseClone方法仍旧为其创建了副本。也就是说在浅拷贝过程我们应该将字符串看成是值类型。一个简单的深拷贝实现样例如下(建议使用序列化的形式来进行深拷贝)Copyclass Employee:ICloneable{ public string IDCode{get;set;} public int Age{get;set;} public Department Department{get;set;} #region ICloneable成员 public object Clone() { using(Stream objectStreamnew MemoryStream()) { IFormatter formatternew BinaryFormatter(); formatter.Serialize(objectStream,this); objectStream.Seek(0,SeekOrigin.Begin); return formatter.Deserialize(objectStream)as Employee; } } #endregion}同时实现深拷贝和浅拷贝由于接口ICloneable只有一个模棱两可的Clone方法所以如果要在一个类中同时实现深拷贝和浅拷贝只能由我们自己实现两个额外的方法声明为DeepClone和Shallow。Em-ployee的最终版本看起来应该像如下的形式Copy[Serializable]class Employee:ICloneable{ public string IDCode{get;set;} public int Age{get;set;} public Department Department{get;set;} #region ICloneable成员 public object Clone() { return this.MemberwiseClone(); } #endregion public Employee DeepClone() { using(Stream objectStreamnew MemoryStream()) { IFormatter formatternew BinaryFormatter(); formatter.Serialize(objectStream,this); objectStream.Seek(0,SeekOrigin.Begin); return formatter.Deserialize(objectStream)as Employee; } } public Employee ShallowClone() { return Clone()as Employee; }}14.利用dynamic来简化反射实现dynamic是Framework 4.0的新特性。dynamic的出现让C#具有了弱语言类型的特性。编译器在编译的时候不再对类型进行检查编译器默认dynamic对象支持开发者想要的任何特性。比如即使你对GetDynamicObject方法返回的对象一无所知也可以像如下这样进行代码的调用编译器不会报错Copydynamic dynamicObjectGetDynamicObject();Console.WriteLine(dynamicObject.Name);Console.WriteLine(dynamicObject.SampleMethod());当然如果运行时dynamicObject不包含指定的这些特性如上文中带返回值的方法SampleMethod运行时程序会抛出一个RuntimeBinderException异常“System.Dynamic.ExpandoObject”未包含“Sam-pleMethod”的定义。var与dynamic有巨大的区别var是编译器的语法糖dynamic是运行时解析在编译期时编译器不对其做任何检查。反射使用不使用dynamic方式CopyDynamicSample dynamicSamplenew DynamicSample();var addMethodtypeof(DynamicSample).GetMethod(Add);int re(int)addMethod.Invoke(dynamicSample,new object[] {1,2});使用dynamic方式Copydynamic dynamicSample2new DynamicSample();int re2dynamicSample2.Add(1,2);建议始终使用dynamic来简化反射实现。总结在大部分应用情况下“效率”并没有那么高的地位灵活性更重要。在部分情况下“灵活性”并没有那么高的地位效率最重要。原文地址https://www.cnblogs.com/zhan520g/p/11014918.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com