如有不理解,请留言,开始!

1. 正确操作字符串

拼接字符串一定要考虑使用 StringBuilder ,默认长度为16,实际看情况设置。

StringBuilder本质: 是以非托管方式分配内存。

同时StringFormat方法 内部也是使用StringBuilder进行字符串格式化。

2. 使用默认转型方法

类型的转换运算符 :每个类型内部都有一个方法(运算符),分为隐式转换和显示转换。

自己实现隐式转换:

puclic static implicit operator Ip(string ip)

{

Ip iptemp=new Ip(ip);

return iptemp;

}

使用类型内置的Parse、TryParse、 ToString、ToDouble、 ToDateTime

使用帮助类提供的方法: System.Convert类、 System.BitConverter类来进行类型的转换。

使用CLR支持的类型:父类和子类之间的转换。

3. 区别对待强制转型与as和is

为了编译更强壮的代码,建议更常使用as和is

什么时候使用as

如果类型之间都上溯到了某个共同的基类,那么根据此基类进行的转型(即基类转型为子类本身)应该使用as。子类与子类之间的转型,则应该提供转换操作符,以便进行强制转型。

as操作符永远不会抛出异常,如果类型不匹配(被转换对象的运行时类型既不是所转换的目标类型,也不是其派生类型),或者转型的源对象为null,那么转型之后的值也为null。

什么时候使用is

as操作符有一个问题,即它不能操作基元类型。如果涉及基元类型的算法,就需要通过is转型前的类型来进行判断,以避免转型失败。

4.TryParse比Parse好

这个肯定好,不说了。安全

5.使用int?来确保值类型也可以为null

基元类型为什么需要为null?考虑两个场景:

数据库支持整数可为空

数据在传输过程中存在丢失问题,导致传过来的值为null

写法: int?i=null;

语法T?是Nullable<T>的简写,两者可以相互转换。可以为null的类型表示其基础值类型正常范围内的值再加上一个null值。例如,Nullable<Int32>,其值的范围为-2 147 483 648~2 147 483 647,再加上一个null值。

?经常和??配合使用,比如:

Copyint?i=123;

int j=i??0;

6.区别readonly和const的使用方法

使用const的理由只有一个,那就是效率。之所以说const变量的效率高,是因为经过编译器编译后,我们在代码中引用const变量的地方会用const变量所对应的实际值来代替。比如: const=100, 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 familyIncome=mikeIncome+roseIncome; 阅读一目了然。通过使用opera-tor关键字定义静态成员函数来重载运算符,让开发人员可以像使用内置基元类型一样使用该类型。

10.创建对象时需要考虑是否实现比较器

有特殊需要比较的时候就考虑。集合排序比较通过linq 也可以解决。

11.区别对待==和Equals

无论是操作符“==”还是方法“Equals”,都倾向于表达这样一个原则:

对于值类型,如果类型的值相等,就应该返回True。

对于引用类型,如果类型指向同一个对象,则返回True。

注意

由于操作符“==”和“Equals”方法从语法实现上来说,都可以被重载为表示“值相等性”和“引用相等性”。所以,为了明确有一种方法肯定比较的是“引用相等性”,FCL中提供了Object.ReferenceEquals方法。该方法比较的是:两个示例是否是同一个示例。

对于string这样一个特殊的引用类型,微软觉得它的现实意义更接近于值类型,所以,在FCL中,string的比较被重载为针对“类型的值”的比较,而不是针对“引用本身”的比较。

12.重写Equals时也要重写GetHashCode

除非考虑到自定义类型会被用作基于散列的集合的键值;否则,不建议重写Equals方法,因为这会带来一系列的问题。

集合找到值的时候本质上是先去 查找HashCode,然后才查找该对象来比较Equals

注意

重写Equals方法的同时,也应该实现一个类型安全的接口IEquatable<T>,比如 :class Person:IEquatable

13.为类型输出格式化字符串

有两种方法可以为类型提供格式化的字符串输出。

一种是意识到类型会产生格式化字符串输出,于是让类型继承接口IFormattable。这对类型来说,是一种主动实现的方式,要求开发者可以预见类型在格式化方面的要求。

更多的时候,类型的使用者需为类型自定义格式化器,这就是第二种方法,也是最灵活多变的方法,可以根据需求的变化为类型提供多个格式化器。

一个典型的格式化器应该继承接口IFormatProvider和ICustomFomatter

14.正确实现浅拷贝和深拷贝

浅拷贝

将对象中的所有字段复制到新的对象(副本)中。其中,值类型字段的值被复制到副本中后,在副本中的修改不会影响到源对象对应的值。而引用类型的字段被复制到副本中的是引用类型的引用,而不是引用的对象,在副本中对引用类型的字段值做修改会影响到源对象本身。

深拷贝

同样,将对象中的所有字段复制到新的对象中。不过,无论是对象的值类型字段,还是引用类型字段,都会被重新创建并赋值,对于副本的修改,不会影响到源对象本身。

无论是浅拷贝还是深拷贝,微软都建议用类型继承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 objectStream=new MemoryStream())

{

IFormatter formatter=new 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 objectStream=new MemoryStream())

{

IFormatter formatter=new 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 dynamicObject=GetDynamicObject();

Console.WriteLine(dynamicObject.Name);

Console.WriteLine(dynamicObject.SampleMethod());

当然,如果运行时dynamicObject不包含指定的这些特性(如上文中带返回值的方法SampleMethod),运行时程序会抛出一个RuntimeBinderException异常:“System.Dynamic.ExpandoObject”未包含“Sam-pleMethod”的定义。

var与dynamic有巨大的区别

var是编译器的语法糖

dynamic是运行时解析,在编译期时,编译器不对其做任何检查。

反射使用

不使用dynamic方式

CopyDynamicSample dynamicSample=new DynamicSample();

var addMethod=typeof(DynamicSample).GetMethod("Add");

int re=(int)addMethod.Invoke(dynamicSample,new object[] {1,2});

使用dynamic方式

Copydynamic dynamicSample2=new DynamicSample();

int re2=dynamicSample2.Add(1,2);

建议:始终使用dynamic来简化反射实现。

总结

在大部分应用情况下,“效率”并没有那么高的地位,灵活性更重要。在部分情况下,“灵活性”并没有那么高的地位,效率最重要。

c#语言规范所在文件夹,C#规范整理·语言要素相关推荐

  1. vue文件命名规范和文件夹命名规范

    views 命名 views 文件夹下面是由 以页面为单位的vue文件 或者 模块文件夹 组成的,放在 src 目录之下,与 components.assets 同级. views 下的文件夹命名 v ...

  2. bat 批处理切换到当前脚本所在文件夹

    bat 批处理切换到当前脚本所在文件夹 切换到当前脚本所在的文件夹 ? 1 cd  %~dp0 另外附上一些bat基本内容 ------------------------------ 批处理常用命令 ...

  3. windows 中 Eclipse 打开当前文件所在文件夹

    windows 中 Eclipse 打开当前文件所在文件夹 默认情况下使用eclipse打开当前文件所在文件夹很麻烦,需要右键点击 Package Explorer 中的节点选择属性,然后复制路径,再 ...

  4. r指引到文件夹_R语言中进行文件夹及文件夹内文件操作范例

    rm(list=ls()) path = 'J:/lab/EX29 –在R语言中进行文件(夹)操作' setwd(path) cat("file A\n", file=" ...

  5. Python语言学习之文件夹那些事:python和文件夹的使用方法之详细攻略

    Python语言学习之文件夹那些事:python和文件夹的使用方法之详细攻略 目录 Python与文件夹那些事 1.创建/删除文件/文件夹 1.创建文件夹

  6. win10电脑服务器在哪个文件夹下,Win10桌面背景在哪个文件夹?Win10桌面背景所在文件夹介绍...

    最近有Win10用户反映,之前电脑有设了张很好看的桌面背景,但后来不小心给换成了别的,现在想换回来,却不知道要在哪个文件夹找那张桌面背景,用户为此非常困恼.那么,Win10桌面背景在哪个文件夹呢?下面 ...

  7. VB6调用API打开目标文件所在文件夹且选中目标文件

    Option Explicit ' 模块名称: mOpenFolderAndSetFileFocus '     作者: 唐细刚 '     时间: 2010-08-22 '     功能: VB6调 ...

  8. 因更改注册表而导致无法打开QQ文件所在文件夹

    因更改注册表而导致无法打开QQ文件所在文件夹 解决办法 -用火绒的系统修复扫描即可:

  9. 为快捷方式文件(lnk文件)右键菜单添加“打开所在文件夹”

    想打开快捷方式所在的文件夹,在Windows Server平台下,可以点击鼠标右键,选择"打开文件位置".但在非Windows Server平台下(楼主本人使用的XP系统),却没有 ...

最新文章

  1. java对象的访问定位_JVM创建对象及访问定位过程详解
  2. 机器学习(李航统计学习方法)
  3. SQL Server 2017 2019 Linux(Centos、Unbuntu16.04、Unbuntu18.04、Unbuntu20.04)安装过程详解
  4. JVM学习笔记(一)------基本结构
  5. spring的service不启动事务的配置。
  6. 关于CSS3实现响应式布局的一些概念和术语
  7. 互联网日报 | 6月19日 星期六 | 京东618累计下单金额超3438亿元;爱回收正式登陆纽交所;欧洲杯官方小程序上线支付宝...
  8. MySQL数据库导入代码_mysql数据库导入导入代码
  9. python打包,上传包知识点学习
  10. 如何查找ADI原厂提供的DSP技术资料
  11. 目前最新全国行政区域JSON数据截止2015年9月30日
  12. 基于昇腾AI异构计算架构CANN的通用目标检测与识别一站式方案初体验
  13. windows 的cmd设置代理方法
  14. 联想装win7驱动遇到问题的解决
  15. 艾美捷双链RNA定量试剂盒作用盒原理分析
  16. php中的==和===的用法及区别
  17. nagios监控安装配置文档+139邮箱报警
  18. 浅析YUV422模式
  19. Maven 权威指南英文
  20. java获取wsdl命名空间_Web服务 – WSDL中的targetNamespace和命名空间

热门文章

  1. 火焰传感器感应有火亮灯代码_智能无线感应灯火了,光感人感2种传感器感应,做照明品牌的几光...
  2. mysql登陆三小时平均值图片_Mysql每小时平均值,间隔从半小时开始
  3. php study是什么,phpstudy与wamp区别的区别是什么?
  4. Pycharm最新版本安装教程
  5. python下载在哪个盘_Windows下载安装python详情和注意事项
  6. 我的Go+语言初体验——(7)Go+ 分数型有理数数据类型
  7. html本地缓存未查看信息,不同用户看到了相同的信息-一次web系统缓存问题的解决...
  8. 计算机中丢失了ll是什么意思,丢失了ntoskrnl.exe和hal.ll
  9. mysql have_mysql having的用法
  10. mysql自增id用完了_MySQL 自增 ID 用完了怎么办?