C#中一些易混淆概念

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

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

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

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

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

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则会转换失败

下面是实例源代码:

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 { get; set; }
}

四,数据类型的存储位置

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

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

2)存储在堆中

string,数组,类

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

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

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

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

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

②然后在堆中开辟连续的4块内存空间

③堆中开辟连续的4块内存空间返回类型为地址,即new  int[4]表达式返回的是地址

示意图如下:

 五,C#方法调用

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

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只能用来修饰一维数组

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);
}
}

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

       //声明一个一维数组
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参数侧重于输出,必须在方法内对其赋值

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

正确的使用方法

       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参数侧重于修改,但是也可以不修改参数的值

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进行任何操作!");
}

输出结果如下:

六,属性易混淆点辨别

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

class Study
{
private int nID; //属性的值存储在封装的字段里面
public int NID
{ get { return nID; }
//这里我们给属性赋值
set { nID = value; }
}
}

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

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

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

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

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

     //属性的值类型为bool
private bool gender;
//字段的返回类型为string
public string Gender
{
//get的返回值类型为bool
get{return gender==true?"男":"女";}
//set参数类型为bool
set{gender =value=="男"?true:false;}
}

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

看如下的代码:

     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

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

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

C#中一些易混淆概念总结的更多相关文章

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

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

  2. 【C#小知识】C#中一些易混淆概念总结(六)---------解析里氏替换原则,虚方法 分类: C# 2014-02-08 01:53 1826人阅读 评论(0) 收藏

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

  3. 【C#小知识】C#中一些易混淆概念总结(五)---------继承 分类: C# 2014-02-06 22:05 1106人阅读 评论(0) 收藏

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

  4. 【C#小知识】C#中一些易混淆概念总结(五)---------深入解析C#继承

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

  5. 【C#小知识】C#中一些易混淆概念总结(四)---------解析Console.WriteLine() 分类: C# 2014-02-05 17:18 1060人阅读 评论(0) 收藏

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

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

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

  7. 【C#小知识】C#中一些易混淆概念总结(二)--------构造函数,this关键字,部分类,枚举 分类: C# 2014-02-03 01:24 1576人阅读 评论(0) 收藏

    目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 继上篇对一些C#概念问题进行细节的剖析以后,收获颇多.以前,读书的时候,一句话一掠而 ...

  8. 【C#小知识】C#中一些易混淆概念总结---------数据类型存储,方法调用,out和ref参数的使用

    这几天一直在复习C#基础知识,过程中也发现了自己以前理解不清楚和混淆的概念.现在给大家分享出来我的笔记: 一,.NET平台的重要组成部分都是有哪些 1)FCL (所谓的.NET框架类库) 这些类是微软 ...

  9. 【C#小知识】C#中一些易混淆概念总结(八)---------解析接口 分类: C# 2014-02-18 00:09 2336人阅读 评论(4) 收藏

     这一篇主要来解析关于面向对象中最总要的一个概念--接口. 对于接口来说,C#是有规定使用Interface关键字来声明接口.它的声明是和类一致的.可以说接口就是一个特殊的抽象类.如下代码: cl ...

随机推荐

  1. 自己写CPU第五级(5)——测试逻辑、实现移动和空指令

    我们会继续上传新书<自己写CPU>(未公布),今天是19片,我每星期试试4 5.6 測试程序1--測试逻辑操作实现效果 编写例如以下測试程序用于检验逻辑操作指令是否实现正确,文件名称命名为 ...

  2. 开源项目:底部动作条(BottomSheet)

    底部动作条(BottomSheet)是一个从屏幕底部边缘向上滑出的一个面板,给用户呈现一组功能选项.底部动作条封装了一组简单.清晰.无需额外说明的操作.底部动作条(如下图)可以是列表样式的,也可以是宫 ...

  3. python3使用smtplib发电子邮件

    smtplib模块smtp简单邮件传输协议client实现.对于多功能性,有时,当你要发送带附件的邮件或图片,使用email.mime加载内容. 码,如以下: import smtplib impor ...

  4. android--解--它们的定义tabhost(动态添加的选项+用自己的主动性横向滑动标签+手势切换标签页和内容特征)

    在本文中,解决他们自己的定义tabhost实现,并通过代码集成动态加入标签功能.自己主动标签横向滑动功能.和手势标签按功能之间切换. 我完成了这个完美的解决方案一起以下: 1.定义tabwidget布 ...

  5. Android_显示器本身被卸载应用程序

    1.经jni实现功能 //LOG宏定义 #define LOG_INFO(tag, msg) __android_log_write(ANDROID_LOG_INFO, tag, msg) #defi ...

  6. UVA Getting in Line

    题目例如以下: Getting in Line  Computer networking requires that the computers in the network be linked. T ...

  7. Middleware开发入门

    Middleware开发入门 上篇我们谈了Host和Server的建立,但Host和Server无法产出任何有实际意义的内容,真正的内容来自于加载于Server的Middleware,本篇我们就着重介 ...

  8. sql优化的50中方法

    查询速度慢的原因很多,常见如下几种:    1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)    2.I/O吞吐量小,形成了瓶颈效应.    3.没有创建计算列导致查询不优化 ...

  9. IOS发展--他们控制的定义

    有没有这样的要求,,自定义panel,里面放几个控件,在多个页面中使用此panel. 有三个观点来解决这个问题: 1.自己继承UIView写一个类,在它是在代码的形式加入需要控制.完成布局. 2.使用 ...

  10. Android-Launcher开发之ShortCut(1)

    下面源代码来自Launcher2.3的样例 1.默认每一个应用的主Activity都会自带 <category android:name="android.intent.categor ...