/*自定义导航栏*/

【C#高级编程】忽略基础知识点梳理

     忽略基础知识点梳理

概述:今天打开一本《C#高级编程》值类型与引用类型翻看,发现有些熟悉的知识点跟以往认识很不一样,今天对某些忽略点的在认识做一些总结。以便深刻理解,倘若你也遇到过,以此共享!。

C#基础系列导航


  1. C#实现队列读写操作(一)
  2. 变化多端的列表(二)
  3. VS自动内存管理(垃圾回收集)(三)
  4. C#忽略基础知识点梳理(四)
  5. 什么是框架的接口(五)
  6. 程序集的加载与反射(六)
  7. CLR寄宿和应用程序域(七)
  8. 异常(八)

  预定义数据类型:

      这个里面有个重心点也是很多面试点就是值类型与引用类型。本人已多次总结,这里不再过多解释。那么我想关心什么是预定义类型?预定义类型多么?有多少呢?

       预定义类型是具有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()

 


 

       到此,今天所看到的的细节问题基本总结完了。明天由于还要早起,暂时到这吧!

 

posted @ 2013-03-26 22:54  伏草惟存  阅读(2886)  评论(6编辑  收藏  举报