【C#高级编程】忽略基础知识点梳理
忽略基础知识点梳理
概述:今天打开一本《C#高级编程》值类型与引用类型翻看,发现有些熟悉的知识点跟以往认识很不一样,今天对某些忽略点的在认识做一些总结。以便深刻理解,倘若你也遇到过,以此共享!。
C#基础系列导航
- C#实现队列读写操作(一)
- 变化多端的列表(二)
- VS自动内存管理(垃圾回收集)(三)
- C#忽略基础知识点梳理(四)
- 什么是框架的接口(五)
- 程序集的加载与反射(六)
- CLR寄宿和应用程序域(七)
- 异常(八)
预定义数据类型:
这个里面有个重心点也是很多面试点就是值类型与引用类型。本人已多次总结,这里不再过多解释。那么我想关心什么是预定义类型?预定义类型多么?有多少呢?
预定义类型是具有CTS标准规范的类型,他们并不内置在C#中,而是内置的.NET Framework中。其他类型都来源于预定义类型的继承。C#预定义类型一共有15个,其中值类型13个(sbyte,short,int,long,byte,ushort,uint,ulong)2个浮点类型(float,dpuble)和1个decimal型,1个bool型,1个字符型(char)和2个预定义引用类型(object,string),object父类毋庸置疑,但是string的引用类型就显得比较特殊了。
String引用类型有何特殊?
static void Main(string[] args)
{
string s1 = "hello Tom!";
string s2 = s1;
Console.WriteLine(s1);
Console.WriteLine(s2);
Console.Read();
}
输出结果1:
修改s1数据:
static void Main(string[] args)
{
string s1 = "hello Tom!";
string s2 = s1;
s1 = "New hello Tom!";
Console.WriteLine(s1);
Console.WriteLine(s2);
Console.Read();
}
运行结果2:
很明显结果是不一致的。原因在于:
结果1:s1引用类型分配在堆中。s2对象指向s1地址索引这个没问题!相信大家都能理解,这个不在详细描述,随后咱们反汇编一下!
结果2:s1原先在堆分配内存中分配地址1(hello Tom!),现在对s1对象重新赋值。相当于new s1.那么堆自然会给s1分配新内存地址2(new hello Tom!).然而s2依旧指向地址1(hello Tom!)中.运行后自然结果不同。
为了详细剖析咱们想想。根据结果不同,肯定s2的内存分配大小更大,而且在调用时s1和s2在第一次调用同一个地址,第二次肯定不同。我们的猜想对于不对?需要实际验证,调用两者反汇编代码:
IL1:
IL2:结果2地内存大小偏大,我们猜想一正确。IL_0009是加载新的string,我们验证没错。
下面了解下有关编译C#文件更多内容
C#代码是托管代码我们所知道的。其原理就是c#代码经过相应的C#编译器(CSC.exe)编译的IL语言。这一点与C,C++,JAVA都是一样的,它们也同样对应相应编译器编译到IL。这里主要介绍C#编译器。其编译选项主要有哪些呢?
1./t:exe 输出控制台应用程序。
2,/t:library 输出带有清单(Il和元数据等)类库
3,/t:modult 输出没有清单的组件
4,/t:winexe 输出windows应用程序(么有控制台窗口)
具体使用:咱们以类库Librayry.cs文件为例。其经过生成后为Librayry.dll。命令编译为:csc /t:library Librayry.cs(同vs中生成一样效果)
控制台I/O问题,也许还有你所不知道的?
1,一个算法输出如下格式:1,空格会显示输出,{m,n}m是表示第m个索引一般0到m,n是宽度值
int i=330;
int j = 30;
Console.WriteLine(" {0,4}\n+{1,4}\n-----\n {2,4}", i, j, i + j);
Console.ReadKey();
2,带有美元符号控制格式输出
decimal i=345.34m;
decimal j = 76.7m;
Console.WriteLine(" {0,9:C2}\n+{1,9:C2}\n-----------\n {2,9:C2}", i, j, i + j);
Console.ReadKey();
3,也可以占位符表示:
double d = 0.544;
Console.WriteLine(" {0:#.00}", d);
Console.ReadKey();
下面就介绍下C#预处理器指令吧!
熟悉c与C++开发的预定义指令一定也不陌生,但是我开始学习C#时以为C#没有预定义概念,应该平常就不会用到它。其实这也正是其作为托管代码的原因所在,C#同样具有与预处理指令。就像内存分配一样,C#不需要手动分配,托管堆会自动分配(上面string分析中结果1的30个大小内存就是自动分配,记得吧?)预处理指令很好认,开头都是#
1,#define和#undef
这里的#define不是实际代码的一部分,只是告诉编译器它定义对象的存在。只在编译代码时存在
#undef,显而易见,这个就相当于删除定义啦
2,#if,#elif(else if),#else ,#endif
这里同样是成对存在的,使用方法与平常if语句一样,但是注意这里;代码演示吧!
这是粘贴出来的,原始定义debug,这里不存在,所有代码编译不会通过,代码部分为灰色。
我强制拿一句Console.ReadKey();运行结果是空白:
3,#warning和#error
这个大家肯定非常熟悉,我们编译出错警告都会遇到,究竟怎么出现呢?原理是什么?
当编译器遇到它们两个会产生警告和错误。如果编译器遇到#warning时候,会显示其指令后面的代码,这个过程也是C#对应编译器实现的。然后继续往下运行。但是如果遇到#error会显示错误信息,立即退出编译,并且不会产生IL代码。即便查看也是没有的
4#region和#endregion
#region 预编译#If应用
#if debug
double d = 0.544;
Console.WriteLine(" {0:#.00}", d);
Console.ReadKey();
#endif
Console.ReadKey();
#endregion
点击节点
这个过程中编译器识别这对指令,可以让代码块折叠,更好代码布局和显示。这个过程中它们好像没有什么用,不影响编译过程。
C#编程规则异常重要!
C#规范编程,这样对于自己也是好的风格,思路清晰,让别人看起来也清晰明了。特别团队合作和别人维护都很重要!(个人总结几点)
1,命名空间异常重要,有时候可能在你都计算机可以,移植到另一台就命名冲突。故采用公司名/个人名.项目名称:如zhangsan.demo
2,私有变量头字母小写:如myTd
3,公用的或者保护类型:如MyId
4,必须字母或者下划线开头,可以追加数字:_myId
5,不能包含关键字,但是加@可以:如@int
6属性和方法尽可能让人能够一看即懂:如:SetPassword()
到此,今天所看到的的细节问题基本总结完了。明天由于还要早起,暂时到这吧!
作者:白宁超,工学硕士,现工作于四川省计算机研究院,研究方向是自然语言处理和机器学习。曾参与国家自然基金项目和四川省科技支撑计划等多个省级项目。著有《自然语言处理理论与实战》一书。 自然语言处理与机器学习技术交流群号:436303759 。
出处:http://www.cnblogs.com/baiboy/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。