这几天一直在复习C#基础知识,过程中也发现了自己以前理解不清楚和混淆的概念。现在给大家分享出来我的笔记:

一,.NET平台的重要组成部分都是有哪些

1)FCL (所谓的.NET框架类库)

这些类是微软事先定义好的。

例如当我们新创建一个windows窗体应用程序是,VS会帮我们自动生成下面的代码:

1
2
3
using System;
using System.Collections.Generic;
using System.Text;

这些就是微软事先为程序员定义好的类库。程序员可以直接使用的。

2)CLR (所谓的公共语言运行时)

创建部署.NET程序的必备环境

使用C#,F#,VB等语言都可以来创建.NET应用程序。这时候就需要一个公共语言规范,来把不同的语言解释成.NET FramWork认识的东西。

二,什么是程序集

程序集主要有MSIL组成(所谓的微软中间语言,主要由dll文件组成)

不同编程语言程序被.NET FrameWork编译成程序集(dll文件),当程序需要被执行时,通过CLR中的JIT(及时编译器)编译成本地代码,并将指令发送给CPU执行。

程序集一般有两种:.dll和.exe文件(但是不是所有的dll和exe都叫程序集)

比如:我们在同一个解决方案下,建立多个应用程序或者类库文件。这些程序或者类库编译后就会变成不同的程序集。他们之间是相互独立的。之间如果想要相互访问,需要添加引用。

三,Parse转换和Convert转换的区别

1)Parse转换

①Parse转换只能转换字符串

②自变量是指定的数据类型才可以转换成功

下面的是.NET Reflector编译的源代码

2)Convert转换

①可以转换其他类型(如:类)

②与Parse的区别就是,转换前会对被转换的对象进行判断,如果对象为null则会转换失败

下面是实例源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Program
    {
        static void Main(string[] args)
        {
            string a = Console.ReadLine();
            //Parse只可以转换字符串
            int b = Int32.Parse(a);
            //Convert可以转换类等对象
            ParseNumber parNum = new ParseNumber();
            //这种写法编译器会报错
            //int b = Int32.Parse(parNum);
            int c = Convert.ToInt32(parNum);
            Console.WriteLine(b);
            Console.WriteLine(b.GetType());
            Console.ReadKey();
        }
    }
    class ParseNumber
    {
        private int nunm;
        public int Num { getset; }
    }

四,数据类型的存储位置

1)存储在栈中的数据类型

所有数值类型,char,bool,枚举,结构体

2)存储在堆中

string,数组,类

管这些类型,他们的变量的声明都是保存在栈里,真实的对象保存在堆里面,栈里面的变量存储打的是对象的地址。

下面以数组来简单说一下这个问题:

1
2
//声明一个一维数组
   int[] arr = new int[4];

那么这个表达式的执行顺序是什么呢?

①首先程序会在栈中开辟一段名为arr的int[]类型的空间

②然后在堆中开辟一个int[]对象,再该对象中会有4块连续的内存空间

③堆中的对象返回类型为地址,即new  int[4]表达式返回的是地址

示意图如下:

五,C#方法调用

1)在C#中我们可以给参数传递默认值,所以当我们调用这个方法的时候,可以不给这个参数传递值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static void Main(string[] args)
        {
            //声明一个一维数组
            int[] arr = new int[4];
            Program pro = new Program();
       //直接调用,没有传递参数值
            pro.para();
                                                                                          
        }
        public void para(int i=5)
        {
            Console.WriteLine(i);
            Console.ReadKey();
        }

2)带默认参数的方法,默认值必须放在最右侧

下面的写法编译器会报错

3)方法的可变参数

①可变参数被Params

②Params只能用来修饰一维数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static void Main(string[] args)
        {
            //声明一个一维数组
            int[] arr = new int[4];
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = i;
            }
            Program pro = new Program();
            pro.para();
            //传递一位数组arr
            pro.param(arr);
            Console.ReadKey();
        }
        //params用来修饰一维数组
        public void param(params int[] arr)
        {
            foreach (var item in arr)
            {
                Console.WriteLine(item);
            }
        }

③给可变参数赋值的时候可以直接传递数组元素

1
2
3
4
5
6
7
8
9
10
11
12
13
//声明一个一维数组
            int[] arr = new int[4];
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = i;
            }
            Program pro = new Program();
            pro.para();
            //传递一位数组arr
            pro.param(arr);
            //直接传递数组元素,调用时会自动将这些数封装成数组,并将数组传递
            pro.param(0, 1, 2, 3);
            Console.ReadKey();

④与默认参数一样,可变参数的声明必须放在方法参数的最后

4)方法的out和ref参数

①out参数侧重于输出,必须在方法内对其赋值

如下图的声明编译器会报错

正确的使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static void Main(string[] args)
        {
            //声明参数m
            int m=0;
            Program pro = new Program();
            //传递参数m,必须带有out参数标识
            pro.outPara( out m);
            Console.WriteLine(m);
            Console.ReadKey();
        }
        //out参数侧重于输出,必须在方法内对其赋值
        public void outPara(out int i)
        {
            //方法内部必须对out参数进行赋值
            i=5;
        }

②ref参数侧重于修改,但是也可以不修改参数的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static void Main(string[] args)
        {
            //声明参数m
            int m=0;
            Program pro = new Program();
            //传递参数m,必须带有out参数标识
            pro.outPara( out m);
       //ref参数传递之前必须对其赋值,因为在方法内部可能会用到该参数
            pro.refPara(ref m);
            //Console.WriteLine(m);
            Console.ReadKey();
        }
        //
        public void refPara(ref int i)
        {
            Console.WriteLine("可以不对参数i进行任何操作!");
        }

输出结果如下:

六,属性易混淆点辨别

①属性本身不存值,值是存在这个属性所封装的字段里面

1
2
3
4
5
6
7
8
9
10
11
12
class Study
    {
        private int nID;
        //属性的值存储在封装的字段里面
        public int NID
        {
                                                              
            get return nID; }
            //这里我们给属性赋值
            set { nID = value; }
        }
    }

通过访问属性字段获取字段的值

1
2
3
Study stu = new Study();
           //通过访问属性字段获取字段的值
           int nID = stu.NID;

②属性的返回值类型和字段的值类型没有关系

1
2
3
4
5
6
7
8
//属性的值类型为bool
        private bool gender;
        //字段的返回类型为string
        public string Gender
        {
            get{return gender==true?"男":"女";}
            set{gender =value=="男"?true:false;}
        }

属性的返回值类型决定了get返回值的类型和set参数的类型

1
2
3
4
5
6
7
8
9
10
//属性的值类型为bool
        private bool gender;
        //字段的返回类型为string
        public string Gender
        {
            //get的返回值类型为bool
            get{return gender==true?"男":"女";}
            //set参数类型为bool
            set{gender =value=="男"?true:false;}
        }

③自动属性到底是怎么回事?

看如下的代码:

1
2
3
4
5
6
7
private string strName;
        //自动属性封装strName
        public string StrName
        {
            get;
            set;
        }

这就是所谓的自动属性封装字段。在非自动属性中,程序默认的会有value值来给字段赋值,但是在自动属性中是怎么赋值的呢?

我们使用.NET Reflector反编译来看源代码:

这是我们封转的属性代码:

反编译set函数源代码:

我们可以看到.NET会默认为我们的程序生成一个成员变量<StrName>k__BackingField

get函数的源代码:

返回的也是该成员变量;

那么什么时候可以使用自动属性呢?

如果对一个字段取值和赋值的时候没有任何逻辑验证并且可读可写的时候,就可以使用自动属性。

七,C#类声明易混淆知识点

①首先给大家说明一个问题就是,文件名和类名必须是一样的么(就是我们在创建类的时候要命明,这个时候会默认的生成一样的类名称)?

如图所示

这个是必须的么?

我们尝试修改类名称为ChildName,然后访问类

可以看到我们要访问类,需要通过类名称访问而与文件名没有关系。

②类表达式的执行顺序和其意义

  Study stu = new Study();

编译器执行代码的时候,

首先会先在栈中开辟一块类型为Study的内存空间放置变量stu

然后在堆中创建该变量的对象

然后调用该对象的构造函数,并且返回该对象在堆中的地址。

好吧,到这里,这次的分享就到此结束了。大家如果阅读的过程中有什么问题,可以跟我留言交流。

本文转自yisuowushinian 51CTO博客,原文链接:http://blog.51cto.com/yisuowushinian/1352834,如需转载请自行联系原作者

C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用...相关推荐

  1. 【C#小知识】C#中一些易混淆概念总结(七)---------解析抽象类,抽象方法

    目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 [C#小知识]C#中一些易混淆概念总结(二)--------构造函数,this关键字 ...

  2. 【C#小知识】C#中一些易混淆概念总结(三)---------结构,GC,静态成员,静态类...

    目录: [C#小知识]C#中一些易混淆概念总结 [C#小知识]C#中一些易混淆概念总结(二) ---------------------------------------分割线----------- ...

  3. render在python中的含义_python面试中常见易混淆概念

    可变数据类型和不可变数据类型 基本数据类型都是不可变数据类型 数字,字符串,布尔值,元组 数据结构(容器)都是可变数据类型 列表,字典,集合 不同下划线变量的含义 _单下划线开头:弱"内部使 ...

  4. 数字电视的几个易混淆概念

      了解数字电视需要分清的五个易混淆概念 2008年北京奥运会一天天在临近,奥组委承诺北京奥运会将使用高清信号直播.为了让全国的观众收看到在自己家门口举行的这一盛大的体育赛事,广电总局已经开始在全国推 ...

  5. java常量和变量 注意事项,建议1: 不要在常量和变量中出现易混淆的字母

    第1章 Java开发中通用的方法和准则 The reasonable man adapts himself to the world;the unreasonable one persists in ...

  6. js中的4种函数调用模式:函数调用、方法调用、构造器调用、间接调用

    全栈工程师开发手册 (作者:栾鹏) js系列教程4-函数.函数参数教程全解 js中的4种函数调用模式 javascript一共有4种调用模式:函数调用模式.方法调用模式.构造器调用模式和间接调用模式. ...

  7. H.264中的一些易混淆概念

    Q:PSNR 峰值信噪比 Q:是根据它来取qp是不是? A:不是, 和QP没有直接关系, 但是QP的选择会影响到PSNR Q: 如果不用率失真最优化, 为什么选择SATD+delta×r(mv,mod ...

  8. EMV中易混淆概念总结

     CDOL(卡风险管理数据对象列表):GAC命令中需要传送给卡片的数据对象列表.CDOL是终端在读应用记录处理过程中从卡片中读取的 TDOL(交易证书数据对象列表):列出生成交易证书(TC)哈希计 ...

  9. 线代[2]|对极易混淆概念的梳理—线性相关与线性无关、极大线性无关部分组与秩与基础解系、向量空间的基与维数

    原创首发于CSDN,转载请注明出处(CSDN:古希腊的汉密士),谢谢! 文章目录 一般形式的线性方程组 线性相关与线性无关 线性极大无关部分组与秩与基础解系 |齐次线性方程组的解 向量空间的基与维数 ...

最新文章

  1. python在办公上的应用_Python 应用 办公自动化之 Excel(上)
  2. boost::geometry::intersection用法的测试程序
  3. 文献记录(part46)--Building Outlier Detection Ensembles by Selective Parameterization of ...
  4. python2.7安装pip_RobotFramework安装过程遇到的问题(电脑同时安装python2和3)
  5. Linux服务之nginx服务篇一(概念)
  6. python面试文件操作_python基础-三分钟搞定面试官爱问的【文件操作】
  7. selenium测试(Java)-- 显式等待(九)
  8. LeedCode知识点之位运算
  9. python 基础知识复习巩固
  10. 使用Grafana+loki+promtail入门级部署分布式日志系统(windows环境)
  11. MS08067 知识星球 “网络安全应急响应训练班”,限时免费加入~
  12. Linux用户管理:新建用户组和新建用户
  13. 荣耀XIO升级鸿蒙,距断供不到10天 华为大招来了:不止鸿蒙
  14. Correct the classpath of your application so that it contains a single, compatible version oforg.spr
  15. Axure与markman
  16. 莫纳什大学计算机专业在哪个校区,莫纳什大学校区几个
  17. vue动态拼接图片路径、img地址拼接问题 [模板字符串]
  18. 摄像头poe供电原理_poe供电模块原理图
  19. 由于之前的错误,Context[]启动失败(SSM)
  20. TriSun PDF to X中文版批量pdf转换功能

热门文章

  1. 今天,我辞去了亚马逊年薪 50 万美金的工作!
  2. mac for docker访问宿主机服务
  3. [Server] 服务器配置SSH登录邮件通知
  4. 分布式 RPC 框架
  5. 1月份制造业和非制造业PMI双双回升 企稳迹象初显
  6. 背水一战 Windows 10 (40) - 控件(导航类): AppBar, CommandBar
  7. iOS - Socket 网络套接字
  8. Django WSGI Error:class.__dict__ not accessible in restricted mode
  9. 大数据算法系列——布隆过滤器
  10. 网页调用本地播放器的代码支持ie,chroome, 火狐不支持