原网页

复习方法:当解释定义题做一遍就行了(先在word里敲上概念,然后解释概念)
不要太纠结,过一遍

每日必复习,直到熟练

善用面向搜索引擎编程,多去知乎以及其他博客搜集资料提升理解,只要有不会的就去搜索

成员变量
变量是类的属性或数据成员,用于存储数据

成员函数
函数是一系列执行指定任务的语句。类的成员函数是在类内声明的。

成员,指类的成员

实例化
实例化是指在面向对象的编程中,用类创建对象的过程称为实例化。
实例就是对象。

可否理解,类是抽象的,看不见摸不着的,只能形容的东西,(比如猫有腿,眼睛,嘴巴等,形容越多越具体)
对象是实际的,能摆在眼前的,(比如真的见到了一只猫,或者说,我们发动上帝之手,按照类的形容创造了世界上第一只猫,,说的再多,最后也只有实际做出来才有意义)

标识符
标识符是用来识别类、变量、函数或任何其它用户定义的项目。
标识符必须以字母、下划线或 @ 开头,后面可以跟一系列的字母、数字( 0 - 9 )、下划线( _ )、@。
标识符中的第一个字符不能是数字。
标识符必须不包含任何嵌入的空格或符号,比如 ? - +! # % ^ & * ( ) [ ] { } . ; : " ’ / \。
标识符不能是 C# 关键字。除非它们有一个 @ 前缀。 例如,@if 是有效的标识符,但 if 不是,因为 if 是关键字。
标识符必须区分大小写。大写字母和小写字母被认为是不同的字母。
不能与C#的类库名称相同。
就是你的类名,变量名,函数名

C# 关键字
关键字是 C# 编译器预定义的保留字。这些关键字不能用作标识符,在 C# 中,有些关键字在代码的上下文中有特殊的意义,如 get 和 set,这些被称为上下文关键字(contextual keywords)。

C# 数据类型
值类型(Value types)
引用类型(Reference types)
指针类型(Pointer types)

值类型
值类型直接包含数据。
如需得到一个类型或一个变量在特定平台上的准确尺寸,可以使用 sizeof 方法。
Console.WriteLine(“Size of int: {0}”, sizeof(int));
Console.ReadLine();

引用类型
引用类型不包含存储在变量中的实际数据,但它们包含对变量的引用。
ps:(但是引用并不是地址,只是指向地址,引用时内存的别名。指针指向一块内存,内容是所指内存的地址)
换句话说,它们指的是一个内存位置。使用多个变量时,引用类型可以指向一个内存位置。如果内存位置的数据是由一个变量改变的,其他变量会自动反映这种值的变化。内置的 引用类型有:object、dynamic 和 string。

对象(Object)类型
对象(Object)类型 是 C# 通用类型系统(Common Type System - CTS)中所有数据类型的终极基类。Object 是 System.Object 类的别名。所以对象(Object)类型可以被分配任何其他类型(值类型、引用类型、预定义类型或用户自定义类型)的值。但是,在分配值之前,需要先进行类型转换。
当一个值类型转换为对象类型时,则被称为 装箱;另一方面,当一个对象类型转换为值类型时,则被称为 拆箱。
object obj;
obj = 100; // 这是装箱

动态(Dynamic)类型
这是什么?
您可以存储任何类型的值在动态数据类型变量中。这些变量的类型检查是在运行时发生的。
态类型与对象类型相似,但是对象类型变量的类型检查是在编译时发生的,而动态类型变量的类型检查是在运行时发生的。

字符串(String)类型
字符串(String)类型 允许您给变量分配任何字符串值。字符串(String)类型是 System.String 类的别名。它是从对象(Object)类型派生的。字符串(String)类型的值可以通过两种形式进行分配:引号和 @引号。
string 字符串的前面可以加 @(称作"逐字字符串")将转义字符(\)当作普通字符对待
@ 字符串中可以任意换行,换行符及缩进空格都计算在字符串长度之内。
定义引用类型有:class、interface 或 delegate。

指针类型(Pointer types)
指针类型变量存储另一种类型的内存地址。

C# 类型转换
隐式类型转换 - 这些转换是 C# 默认的以安全方式进行的转换, 不会导致数据丢失。例如,从小的整数类型转换为大的整数类型,从派生类转换为基类。
显式类型转换 - 显式类型转换,即强制类型转换。显式转换需要强制转换运算符,而且强制转换会造成数据丢失

C# 变量
一个变量只不过是一个供程序操作的存储区的名字。在 C# 中,每个变量都有一个特定的类型,类型决定了变量的内存大小和布局。
C# 中的变量定义 int i, j, k; (定义就是声明
C# 中的变量初始化 a = 10; 变量可以在声明时被初始化(指定一个初始值

C# 常量
常量是固定值,程序执行期间不会改变。
整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,没有前缀则表示十进制。
整数常量也可以有后缀,可以是 U 和 L 的组合,其中,U 和 L 分别表示 unsigned 和 long。后缀可以是大写或者小写,
定义常量
常量是使用 const 关键字来定义的 。

C# 运算符
运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。

C# 判断 没啥好说的

C# 循环
break 语句终止 loop 或 switch 语句,程序流将继续执行紧接着 loop 或 switch 的下一条语句。
continue 语句引起循环跳过主体的剩余部分,立即重新开始测试条件。

C# 封装
封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中"。在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。C# 封装根据具体的需要,设置使用者的访问权限,并通过 访问修饰符 来实现。一个 访问修饰符 定义了一个类成员的范围和可见性。C# 支持的访问修饰符如下所示:

public:所有对象都可以访问;
private:对象本身在对象内部可以访问;
protected:只有该类对象及其子类对象可以访问
internal:同一个程序集的对象可以访问;
protected internal:访问限于当前程序集或派生自包含类的类型。

C# 方法
一个方法是把一些相关的语句组织在一起,用来执行一个任务的语句块。
在 C# 中,有三种向方法传递参数的方式:值参数,引用参数,输出参数

C# 可空类型(Nullable)
C# 提供了一个特殊的数据类型,nullable 类型(可空类型),可空类型可以表示其基础值类型正常范围内的值,再加上一个 null 值。
< data_type> ? <variable_name> = null;

C# 数组(Array)
数组是一个存储相同类型元素的固定大小的顺序集合。
数组是一个引用类型,所以您需要使用 new 关键字来创建数组的实例。

类是引用类型的数据类型,所以说new不是专门用来给类创建实例的,而是用来给引用类型创建实例的。
比如这里,创建的是数组的实例。

C# 字符串(String)

C# 结构体(Struct)
在 C# 中,结构体是值类型数据结构。它使得一个单一变量可以存储各种数据类型的相关数据。
类 vs 结构
类和结构有以下几个基本的不同点:

类是引用类型,结构是值类型。
结构不支持继承。
结构不能声明默认的构造函数。

C# 枚举(Enum)
枚举是一组命名整型常量。枚举类型是使用 enum 关键字声明的。
C# 枚举是值类型。换句话说,枚举包含自己的值,且不能继承或传递继承。

C# 类(Class)
当你定义一个类时,你定义了一个数据类型的蓝图。这实际上并没有定义任何的数据,但它定义了类的名称意味着什么,也就是说,类的对象由什么组成及在这个对象上可执行什么操作。对象是类的实例。构成类的方法和变量称为类的成员。

C# 中的构造函数
类的 构造函数 是类的一个特殊的成员函数,当创建类的新对象时执行。
构造函数的名称与类的名称完全相同,它没有任何返回类型。

C# 中的析构函数
类的 析构函数 是类的一个特殊的成员函数,当类的对象超出范围时执行。
析构函数的名称是在类的名称前加上一个波浪形(~)作为前缀,它不返回值,也不带任何参数。
析构函数用于在结束程序(比如关闭文件、释放内存等)之前释放资源。析构函数不能继承或重载。

C# 类的静态成员
我们可以使用 static 关键字把类成员定义为静态的。当我们声明一个类成员为静态时,意味着无论有多少个类的对象被创建,只会有一个该静态成员的副本。
关键字 static 意味着类中只有一个该成员的实例。静态变量用于定义常量,因为它们的值可以通过直接调用类而不需要创建类的实例来获取。

C# 继承
继承是面向对象程序设计中最重要的概念之一。继承允许我们根据一个类来定义另一个类,
已有的类被称为的基类,这个新的类被称为派生类。
C# 不支持多重继承。但是,您可以使用接口来实现多重继承

C# 接口(Interface)
接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同 “是什么” 部分,派生类定义了语法合同 “怎么做” 部分。
接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构。

也许:接口就是告诉你,继承了我之后你要实现哪些功能,但是我不告诉你该怎么办,然后派生类来说明这个功能要怎么实现,也就是说,不同派生类可以用不同方法实现同一接口的功能?也就是下面的多态性?

interface IMyInterface
{
// 接口成员
void MethodToImplement();
}
class InterfaceImplementer : IMyInterface//接口的实现与类的继承语法格式类似
{
static void Main()
{
InterfaceImplementer iImp = new InterfaceImplementer();
iImp.MethodToImplement();
}
public void MethodToImplement()//这里就是所谓成员的定义是派生类的责任
{
Console.WriteLine(“MethodToImplement() called.”);
}
}
如果一个接口继承多个接口,那么实现类或结构就需要实现所有接口的成员。

C# 多态性
多态是同一个行为具有多个不同表现形式或形态的能力。在面向对象编程范式中,多态性往往表现为"一个接口,多个功能"。
在静态多态性中,函数的响应是在编译时发生的。在动态多态性中,函数的响应是在运行时发生的。
每个类型都是多态的,因为包括用户定义类型在内的所有类型都继承自 Object

override叫重写

静态多态性
在编译时,函数和对象的连接机制被称为早期绑定,也被称为静态绑定。C# 提供了两种技术来实现静态多态性。分别为:

函数重载
您可以在同一个范围内对相同的函数名有多个定义。函数的定义必须彼此不同,可以是参数列表中的参数类型不同,也可以是参数个数不同。不能重载只有返回类型不同的函数声明。

C# 运算符重载
您可以重定义或重载 C# 中内置的运算符。因此,程序员也可以使用用户自定义类型的运算符。重载运算符是具有特殊名称的函数,是通过关键字 operator 后跟运算符的符号来定义的。与其他函数一样,重载运算符有返回类型和参数列表。

public static Box operator+ (Box b, Box c){Box box = new Box();box.length = b.length + c.length;box.breadth = b.breadth + c.breadth;box.height = b.height + c.height;return box;}

这样子任意两个Box类对象都可以相加了
+, -, !, ~, ++, – 这些一元运算符只有一个操作数,且可以被重载。
+, -, *, /, % 这些二元运算符带有两个操作数,且可以被重载。
==, !=, <, >, <=, >= 这些比较运算符可以被重载。
&&, || 这些条件逻辑运算符不能被直接重载。
+=, -=, *=, /=, %= 这些赋值运算符不能被重载。
=, ., ?:, ->, new, is, sizeof, typeof 这些运算符不能被重载。

动态多态性
C# 允许您使用关键字 abstract 创建抽象类,用于提供接口的部分类的实现。当一个派生类继承自该抽象类时,实现即完成。抽象类包含抽象方法,抽象方法可被派生类实现。
您不能创建一个抽象类的实例。
您不能在一个抽象类外部声明一个抽象方法。
通过在类定义前面放置关键字 sealed,可以将类声明为密封类。当一个类被声明为 sealed 时,它不能被继承。抽象类不能被声明为 sealed。

当有一个定义在类中的函数需要在继承类中实现时,可以使用虚方法。虚方法是使用关键字 virtual 声明的。

虚方法可以在不同的继承类中有不同的实现。对虚方法的调用是在运行时发生的。
动态多态性是通过 抽象类 和 虚方法 实现的。

关于抽象类和接口
资料来源
一、抽象类:
抽象类是特殊的类,只是不能被实例化;除此以外,具有类的其他特性;重要的是抽象类可以包括抽象方法,这是普通类所不能的。抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们。
二、接口:
接口是引用类型的,类似于类,和抽象类的相似之处有三点:
1. 不能实例化;
2. 包含未实现的方法声明;
3. 派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括其他成员);
另外,接口有如下特性:
接口除了可以包含方法之外,还可以包含属性、索引器、事件,而且这些成员都被定义为公有的。除此之外,不能包含任何其他的成员,例如:常量、域、构造函数、析构函数、静态成员。一个类可以直接继承多个接口,但只能直接继承一个类(包括抽象类)。

三、抽象类和接口的区别:
1. 类是对对象的抽象,可以把抽象类理解为把类当作对象,抽象成的类叫做抽象类.而接口只是一个行为的规范或规定,微软的自定义接口总是后带able字段,证明其是表述一类类“我能做。。。”。抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中;
2. 接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法;
3. 一个类一次可以实现若干个接口,但是只能扩展一个父类;
4. 接口可以用于支持回调,而继承并不具备这个特点;
5. 抽象类不能被密封;
6. 抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的;
7.(接口)与非抽象类类似,抽象类也必须为在该类的基类列表中列出的接口的所有成员提供它自己的实现。但是,允许抽象类将接口方法映射到抽象方法上;
8. 抽象类实现了oop中的一个原则,把可变的与不可变的分离。抽象类和接口就是定义为不可变的,而把可变的座位子类去实现;
9. 好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染;
10. 尽量避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。因为继承的层次增多,造成最直接的后果就是当你调用这个类群中某一类,就必须把他们全部加载到栈中!后果可想而知。(结合堆栈原理理解)。同时,有心的朋友可以留意到微软在构建一个类时,很多时候用到了对象组合的方法。比如 asp.net中,Page类,有Server Request等属性,但其实他们都是某个类的对象。使用Page类的这个对象来调用另外的类的方法和属性,这个是非常基本的一个设计原则;
11.如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法。

四、抽象类和接口的使用:
1. 如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单的方法来控制组件版本;
2.如果创建的功能将在大范围的全异对象间使用,则使用接口。如果要设计小而简练的功能块,则使用接口;
3.如果要设计大的功能单元,则使用抽象类。如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类;
4.抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能。

以下是我在网上看到的几个形象比喻。
1.飞机会飞,鸟会飞,他们都继承了同一个接口“飞”;但是F22属于飞机抽象类,鸽子属于鸟抽象类;
2. 就像铁门木门都是门(抽象类),你想要个门我给不了(不能实例化),但我可以给你个具体的铁门或木门(多态);而且只能是门,你不能说它是窗(单继承),一个门可以有锁(接口)也可以有门铃(多实现)。门(抽象类)定义了你是什么,接口(锁)规定了你能做什么(一个接口最好只能做一件事,你不能要求锁也能发出声音吧(接口污染))。

ps:也就是说,在具体的程度上,对象>类>抽象类,平时之前举的例子都是很大的,都可以说是抽象类? 狗—哈士奇—A家的哈士奇

C# 异常处理
异常提供了一种把程序控制权从某个部分转移到另一个部分的方式。C# 异常处理时建立在四个关键词之上的:try、catch、finally 和 throw。
try:一个 try 块标识了一个将被激活的特定的异常的代码块。后跟一个或多个 catch 块。
catch:程序通过异常处理程序捕获异常。catch 关键字表示异常的捕获。
finally:finally 块用于执行给定的语句,不管异常是否被抛出都会执行。例如,如果您打开一个文件,不管是否出现异常文件都要被关闭。
throw:当问题出现时,程序抛出一个异常。使用 throw 关键字来完成。

C# 命名空间(Namespace)
在一个命名空间中声明的类的名称与另一个命名空间中声明的相同的类的名称不冲突
using 关键字
using 关键字表明程序使用的是给定命名空间中的名称。例如,我们在程序中使用 System 命名空间,其中定义了类 Console。
命名空间可以被嵌套,即您可以在一个命名空间内定义另一个命名空间,

C# 预处理器指令
预处理器指令指导编译器在实际编译开始之前对信息进行预处理。
所有的预处理器指令都是以 # 开始。预处理器指令不是语句,所以它们不以分号(;)结束。如#define

C# 正则表达式
看不懂

#文件的输入与输出
一个 文件 是一个存储在磁盘中带有指定名称和目录路径的数据集合。当打开文件进行读写时,它变成一个 流。
从根本上说,流是通过通信路径传递的字节序列。有两个主要的流:输入流 和 输出流。输入流用于从文件读取数据(读操作),输出流用于向文件写入数据(写操作)。//

第二部分,高级教程部分

C# 特性(Attribute)

特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所应用的元素前面的方括号([ ])来描述的。
特性(Attribute)用于添加元数据,如编译器指令和注释、描述、方法、类等其他信息。.Net 框架提供了两种类型的特性:预定义特性和自定义特性。


虽然有点懵,但是还是努力理解了一下
第一个问题,函数参数是object,是指参数数据类型是object(对象类型?)看到加点东西就简单我也是傻了,加什么啊
看到Func还一下子没反应过来,Func就是方法啊,根据字面意思getFuncData(得到方法数据)返回值是类型叫FuncData的数组。
而FuncData准确来说是一个结构体类型,而在这个叫FuncData的结构体里存着一个函数的信息,
给每个类都手写一个FuncData的表,FuncData本身是一个结构,应该是写在类外面的没错,写一个表应该是指在每一个类中将每个方法存到表里
那么回到最初的需求,这个函数可以调用父类里的getFuncData方法获取所有方法数据了,即使不知道也不告诉有什么方法
但是还是不明白这个函数参数是干嘛用的。。

那么也就是说,这个Attribute特性,指的是给类增加某些特性,

完全陌生,例子举得好少,不知道到底是干嘛用,怎么用的。
就不全部复制一遍了,似乎要与下一章 的反射共同使用

C# 反射(Reflection)

知乎的解答(看不懂说实话)

就不能整点实际的练习来学习这些吗,完全懵B

贴上大佬的笔记,两天前写的,真是幸运

using System;
using System.Reflection;//System.Reflection 类的 MemberInfo用于发现与类相关的特性(attribute)。
namespace BugFixApplication
{// 一个自定义特性 BugFix 被赋给类及其成员[AttributeUsage#region//定义了特性能被放在那些前面        (AttributeTargets.Class |//规定了特性能被放在class的前面AttributeTargets.Constructor |//规定了特性能被放在构造函数的前面AttributeTargets.Field |//规定了特性能被放在域的前面AttributeTargets.Method |//规定了特性能被放在方法的前面AttributeTargets.Property,//规定了特性能被放在属性的前面#endregionAllowMultiple = true)]//这个属性标记了我们的定制特性能否被重复放置在同一个程序实体前多次。public class DeBugInfo : System.Attribute//继承了预定义特性后的自定义特性{private int bugNo;private string developer;private string lastReview;public string message;public DeBugInfo(int bg,string dev,string d)//构造函数,接收三个参数并赋给对应实例{this.bugNo = bg;this.developer = dev;this.lastReview = d;}#region//定义对应的调用,返回对应值valuepublic int BugNo{get {return bugNo;}}public string Developer{get{return developer;}}public string LastReview{get{return lastReview;}}//前面有public string message;public string Message//定义了可以通过Message = "",来对message进行赋值。//因为不在构造函数中,所以是可选的{get{return message;}set{message = value;}}/** 这部分可以简写如下* public string Message{get;set;}*/}#endregion[DeBugInfo(45, "Zara Ali", "12/8/2012",Message = "Return type mismatch")][DeBugInfo(49, "Nuha Ali", "10/10/2012",Message = "Unused variable")]//前面定义时的AllowMultiple=ture允许了多次使用在同一地方class Rectangle{protected double length;protected double width;//定义两个受保护的(封装)的成员变量public Rectangle(double l,double w)//构造函数,对两个成员变量进行初始化,公开的{length = l;width = w;}[DeBugInfo(55, "Zara Ali", "19/10/2012",Message = "Return type mismatch")]public double GetArea(){return length * width;}[DeBugInfo(56, "Zara Ali", "19/10/2012")]//因为message是可选项,所以可以不给出//不给出即为null,为空白public void Display(){Console.WriteLine("Length: {0}", length);Console.WriteLine("Width:{0}", width);Console.WriteLine("Area:{0}", GetArea());//常规打印}}class ExecuteRectangle{static void Main(string[] args)//程序入口{Rectangle r = new Rectangle(4.5, 7.5);//实例化r.Display();//执行打印长、宽、面积Type type = typeof(Rectangle);//让type对应这个Rectangle类// 遍历 Rectangle 类的特性foreach (Object attributes in type.GetCustomAttributes(false))//遍历Rectangle的所有特性{DeBugInfo dbi = (DeBugInfo)attributes;//强制转换if(null != dbi)//dbi非空{Console.WriteLine("Bug on: {0}", dbi.BugNo);Console.WriteLine("Developer: {0}", dbi.Developer);Console.WriteLine("Last REviewed: {0}", dbi.LastReview);Console.WriteLine("Remarks: {0}", dbi.Message);}}// 遍历方法特性foreach (MethodInfo m in type.GetMethods())//遍历Rectangle类下的所有方法{foreach (Attribute a in m.GetCustomAttributes(true))//遍历每个方法的特性{DeBugInfo dbi = a as DeBugInfo;//通过 object 声明对象,是用了装箱和取消装箱的概念.//也就是说 object 可以看成是所有类型的父类。//因此 object 声明的对象可以转换成任意类型的值。//通过拆装箱代替强制转换if (null !=dbi)//同理打印{Console.WriteLine("BugFixApplication no: {0},for Method: {1}", dbi.BugNo, m.Name);Console.WriteLine("Developer:{0}", dbi.Developer);Console.WriteLine("Last Reviewed: {0}", dbi.LastReview);Console.WriteLine("Remarks: {0}", dbi.Message);}}}Console.ReadKey();}}
}

先放一放好了。。

C# 属性(Property)

属性(Property) 是类(class)、结构(structure)和接口(interface)的命名(named)成员。类或结构中的成员变量或方法称为 域(Field)。属性(Property)是域(Field)的扩展,且可使用相同的语法来访问。它们使用 访问器(accessors) 让私有域的值可被读写或操作。
属性(Property)不会确定存储位置。相反,它们具有可读写或计算它们值的 访问器(accessors)。
例如,有一个名为 Student 的类,带有 age、name 和 code 的私有域。我们不能在类的范围以外直接访问这些域,但是我们可以拥有访问这些私有域的属性。

ps:变量 或 方法称为域。。

访问器(accessor)声明可包含一个 get 访问器、一个 set 访问器,或者同时包含二者。

抽象类可拥有抽象属性,这些属性应在派生类中被实现。

这个好懂多了

C# 索引器(Indexer)

索引器(Indexer) 允许一个对象可以像数组一样被索引。当您为类定义一个索引器时,该类的行为就会像一个 虚拟数组(virtual array) 一样。您可以使用数组访问运算符([ ])来访问该类的实例。

虚拟数组,就是指像数组,但又不是数组?就像伪代码那样吗?

索引器(Indexer)的用途
索引器的行为的声明在某种程度上类似于属性(property)。就像属性(property),您可使用 get 和 set 访问器来定义索引器。但是,属性返回或设置一个特定的数据成员,而索引器返回或设置对象实例的一个特定值。换句话说,它把实例数据分为更小的部分,并索引每个部分,获取或设置每个部分。
定义一个属性(property)包括提供属性名称。索引器定义的时候不带有名称,但带有 this 关键字,它指向对象实例。

this就是对象实例吧,对象和实例应该是同一个东西,不是说对象的实例

public string Code{get{return code;}set{code = value;}}//这个是属性
public string this[int index]
{get{}set{}
}//这样的是索引器      

属性可以读写对象的字段,而索引器是将对象变成类似数组的东西,然后根据索引读写对象

重载索引器(Indexer)
索引器(Indexer)可被重载。索引器声明的时候也可带有多个参数,且每个参数可以是不同的类型。没有必要让索引器必须是整型的。C# 允许索引器可以是其他类型,例如,字符串类型。

数组的话类型可以不同,但是索引肯定是int,而这个索引器的索引可以是其他类型,比如可以根据int索引找string类型的,并且还可以反过来根据string类型索引找int,

C# 委托(Delegate)

C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。
委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。

委托是对方法的引用,之前的引用类型都是对数据,

声明委托(Delegate)
委托声明决定了可由该委托引用的方法。委托可指向一个与其具有相同标签的方法。
例如,假设有一个委托:
public delegate int MyDelegate (string s);
上面的委托可被用于引用任何一个带有一个单一的 string 参数的方法,并返回一个 int 类型变量。

标签。。是什么。反正,只要参数类型和返回值类型对应就行了

实例化委托(Delegate)
一旦声明了委托类型,委托对象必须使用 new 关键字来创建,且与一个特定的方法有关。当创建委托时,传递到 new 语句的参数就像方法调用一样书写,但是不带有参数。例如:
public delegate void printString(string s);
printString ps1 = new printString(WriteToScreen);

我好乱,方法的对象?应该是委托的对象,委托是一个类,可以有对象,

using System;
delegate int NumberChanger(int n);//居然是放在类外面的,
namespace DelegateAppl
{class TestDelegate{static int num = 10;public static int AddNum(int p){num += p;return num;}public static int MultNum(int q){num *= q;return num;}public static int getNum(){return num;}static void Main(string[] args){// 创建委托实例NumberChanger nc1 = new NumberChanger(AddNum);NumberChanger nc2 = new NumberChanger(MultNum);// 使用委托对象调用方法nc1(25);Console.WriteLine("Value of Num: {0}", getNum());nc2(5);Console.WriteLine("Value of Num: {0}", getNum());Console.ReadKey();}}
}

以前是声明类的对象,由对象调用方法,如果是静态的就直接类名调用,这种委托来调用方法是干嘛用的呢?

委托的多播(Multicasting of a Delegate)
委托对象可使用 “+” 运算符进行合并。一个合并委托调用它所合并的两个委托。只有相同类型的委托可被合并。"-" 运算符可用于从合并的委托中移除组件委托。
使用委托的这个有用的特点,您可以创建一个委托被调用时要调用的方法的调用列表。这被称为委托的 多播(multicasting),也叫组播。

 static void Main(string[] args){// 创建委托实例NumberChanger nc;NumberChanger nc1 = new NumberChanger(AddNum);NumberChanger nc2 = new NumberChanger(MultNum);nc = nc1;nc += nc2;// 调用多播nc(5);Console.WriteLine("Value of Num: {0}", getNum());Console.ReadKey();}

这样岂不是可以排列组合方法了?可能性多了好多

委托(Delegate)的用途
下面的实例演示了委托的用法。委托 printString 可用于引用带有一个字符串作为输入的方法,并不返回任何东西。
我们使用这个委托来调用两个方法,第一个把字符串打印到控制台,第二个把字符串打印到文件:

using System;
using System.IO;
namespace DelegateAppl
{class PrintString{static FileStream fs;static StreamWriter sw;// 委托声明public delegate void printString(string s);// 该方法打印到控制台public static void WriteToScreen(string str){Console.WriteLine("The String is: {0}", str);}// 该方法打印到文件public static void WriteToFile(string s){fs = new FileStream("c:\\message.txt", FileMode.Append, FileAccess.Write);sw = new StreamWriter(fs);sw.WriteLine(s);sw.Flush();sw.Close();fs.Close();}// 该方法把委托作为参数,并使用它调用方法public static void sendString(printString ps){ps("Hello World");}static void Main(string[] args){printString ps1 = new printString(WriteToScreen);printString ps2 = new printString(WriteToFile);sendString(ps1);sendString(ps2);Console.ReadKey();}}
}

委托把方法作为参数,方法又可以把委托作为参数,,这个没问题因为委托本来就是一个类

把字符串打印到文件不是很懂,但是打印到控制台这一步,直接ps(“Hello World”);,不用方法调用委托这个中间的步骤应该也是一样的吧

另外评论区大佬的

// 小张类
public class MrZhang{// 其实买车票的悲情人物是小张public static void BuyTicket(){Console.WriteLine("NND,每次都让我去买票,鸡人呀!");}public static void BuyMovieTicket(){Console.WriteLine("我去,自己泡妞,还要让我带电影票!");}
}//小明类
class MrMing
{// 声明一个委托,其实就是个“命令”public delegate void BugTicketEventHandler();public static void Main(string[] args){// 这里就是具体阐述这个命令是干什么的,本例是MrZhang.BuyTicket“小张买车票”BugTicketEventHandler myDelegate = new BugTicketEventHandler(MrZhang.BuyTicket);myDelegate += MrZhang.BuyMovieTicket;// 这时候委托被附上了具体的方法myDelegate();Console.ReadKey();}
}

总之委托可以调用方法。方法也可以调用委托,并且委托又调用方法。。

C# 事件(Event)

事件(Event) 基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些提示信息,如系统生成的通知。应用程序需要在事件发生时响应事件。例如,中断。
C# 中使用事件机制实现线程间的通信。

通过事件使用委托
事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。包含事件的类用于发布事件。这被称为 发布器(publisher) 类。其他接受该事件的类被称为 订阅器(subscriber) 类。事件使用 发布-订阅(publisher-subscriber) 模型。
发布器(publisher) 是一个包含事件和委托定义的对象。事件和委托之间的联系也定义在这个对象中。发布器(publisher)类的对象调用这个事件,并通知其他的对象。
订阅器(subscriber) 是一个接受事件并提供事件处理程序的对象。在发布器(publisher)类中的委托调用订阅器(subscriber)类中的方法(事件处理程序)。

事件要在类中声明,和委托不同呢,委托既可以在类外也可以在类内。

本实例提供一个简单的用于热水锅炉系统故障排除的应用程序。当维修工程师检查锅炉时,锅炉的温度和压力会随着维修工程师的备注自动记录到日志文件中。

记住需求,这里是将温度和压力记录到日志中

using System;
using System.IO;namespace BoilerEventAppl
{// boiler 类,boiler锅炉class Boiler{private int temp;private int pressure;//温度和压力public Boiler(int t, int p){temp = t;pressure = p;}public int getTemp(){return temp;}public int getPressure(){return pressure;}}// 事件发布器,包含事件和委托的联系class DelegateBoilerEvent//delegate代表{public delegate void BoilerLogHandler(string status);//锅炉log操作者// 基于上面的委托定义事件public event BoilerLogHandler BoilerEventLog;//锅炉事件logpublic void LogProcess(){string remarks = "O. K";Boiler b = new Boiler(100, 12);int t = b.getTemp();int p = b.getPressure();if(t > 150 || t < 80 || p < 12 || p > 15){remarks = "Need Maintenance";}OnBoilerEventLog("Logging Info:\n");OnBoilerEventLog("Temparature " + t + "\nPressure: " + p);OnBoilerEventLog("\nMessage: " + remarks);//调用这个方法时,调用委托,并将这些string参数传入log}protected void OnBoilerEventLog(string message)//事件方法{if (BoilerEventLog != null){BoilerEventLog(message);//这个方法调用了事件,事件又调用了委托,那么委托调用的方法在哪//委托会将信息存入log,问题在于委托需要一个方法来传递数据}}}// 该类保留写入日志文件的条款,不管那么多,总之能存入文件class BoilerInfoLogger{FileStream fs;StreamWriter sw;public BoilerInfoLogger(string filename){fs = new FileStream(filename, FileMode.Append, FileAccess.Write);sw = new StreamWriter(fs);}public void Logger(string info){sw.WriteLine(info);}public void Close(){sw.Close();fs.Close();}}// 事件订阅器,接受事件并提供事件处理程序public class RecordBoilerInfo{static void Logger(string info)//不同类的同名方法吧{Console.WriteLine(info);}//end of Loggerstatic void Main(string[] args){BoilerInfoLogger filelog = new BoilerInfoLogger("e:\\boiler.txt");//实例化日志对象,并初始化一下DelegateBoilerEvent boilerEvent = new DelegateBoilerEvent();//事件发布器boilerEvent.BoilerEventLog += new  DelegateBoilerEvent.BoilerLogHandler(Logger);//从左到右,事件+=委托,解释:因为事件和委托都在事件发布器类里,所以在订阅器里要用类名点,,至于要new,之前委托有说,//就是实例化了一个委托对象,不过还可以类名点类的吗,委托到底是什么,,//然后委托调用了这里的Logger方法boilerEvent.BoilerEventLog += new  DelegateBoilerEvent.BoilerLogHandler(filelog.Logger);//这里又调用了日志类里的logger方法boilerEvent.LogProcess();//事件发布器调用自己的类Console.ReadLine();filelog.Close();}//end of main}//end of RecordBoilerInfo
}

ps:锅炉事件发布器提供了一个要存入数据的事件,事件只是说发生了这件事,而要做出什么样的响应就是在发布器中定义的有联系的委托,因为委托才能调用方法做事情,又因为方法才是执行任务的语句,发布器发布器publisher只负责提供发布事件的功能,而事件是要你将温度和压力存到log中
而订阅器是调用功能的类,但他同时又是提供功能的类。调用了发布器的事件(或者说响应了事件),提供事件的委托所需要的方法(或
说功能),这里是提供了存入log的方法,这个+=不是事件+=,是委托的多播+=。

注意到还没有给方法参数,这两个方法都要求string类型的参数,所以才有了boilerEvent.LogProcess();这句,回到发布器里看这个方法,
(其实感觉把这个写在订阅器里好像也行,,有什么不同之处吗?)(发布器要包含事件和委托的联系?是因为这句话吗)(不写的话就只有两句声明了。。)
!所以说,发布器的功能除了提供事件,还有事件和委托的联系,具体说就比如这里还提供了方法所需的参数,string类型的数据,,也就是除了事件,事件所需要提供的功能也交代了
回到这个方法,调用了事件,但在一开始事件的委托没有方法,现在委托有了两个方法,在将这些参数传入,大功告成,

又是老一套,功能的提供者和调用者,,但是事件说是功能好像有点,,但它确实算是一种功能,功能就是告诉你要做出响应,

C# 集合(Collection)

集合(Collection)类是专门用于数据存储和检索的类。这些类提供了对栈(stack)、队列(queue)、列表(list)和哈希表(hash table)的支持。大多数集合类实现了相同的接口。
集合(Collection)类服务于不同的目的,如为元素动态分配内存,基于索引访问列表项等等。这些类创建 Object 类的对象的集合。在 C# 中,Object 类是所有数据类型的基类。

包括动态数组,堆栈,队列等

C# 泛型(Generic)

泛型(Generic) 允许您延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。换句话说,泛型允许您编写一个可以与任何数据类型一起工作的类或方法。
您可以通过数据类型的替代参数编写类或方法的规范。当编译器遇到类的构造函数或方法的函数调用时,它会生成代码来处理指定的数据类型。下面这个简单的实例将有助于您理解这个概念:

有点像c++里的模板类?

C# 匿名方法

我们已经提到过,委托是用于引用与其具有相同标签的方法。换句话说,您可以使用委托对象调用可由委托引用的方法。
匿名方法(Anonymous methods) 提供了一种传递代码块作为委托参数的技术。匿名方法是没有名称只有主体的方法。
在匿名方法中您不需要指定返回类型,它是从方法主体内的 return 语句推断的。

编写匿名方法的语法
匿名方法是通过使用 delegate 关键字创建委托实例来声明的。例如:

delegate void NumberChanger(int n);
...
NumberChanger nc = delegate(int x)
{Console.WriteLine("Anonymous Method: {0}", x);
};

代码块 Console.WriteLine(“Anonymous Method: {0}”, x); 是匿名方法的主体。
委托可以通过匿名方法调用,也可以通过命名方法调用,即,通过向委托对象传递方法参数。

这个匿名方法的意义在于什么呢?

C# 不安全代码

当一个代码块使用 unsafe 修饰符标记时,C# 允许在函数中使用指针变量。不安全代码或非托管代码是指使用了指针变量的代码块。
指针变量
指针是值为另一个变量的地址的变量即内存位置的直接地址。就像其他变量或常量,您必须在使用指针存储其他变量地址之前声明指针。
您可以使用 ToString() 方法检索存储在指针变量所引用位置的数据。p->ToString()

由于C#中声明的变量在内存中的存储受垃圾回收器管理;因此一个变量(例如一个大数组)有可能在运行过程中被移动到内存中的其他位置。如果一个变量的内存地址会变化,那么指针也就没有意义了。

解决方法就是使用fixed关键字来固定变量位置不移动。fixed(int *ptr = int[5]) {//…}

C# 多线程

线程 被定义为程序的执行路径。每个线程都定义了一个独特的控制流。如果您的应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。
线程是轻量级进程。一个使用线程的常见实例是现代操作系统中并行编程的实现。使用线程节省了 CPU 周期的浪费,同时提高了应用程序的效率。
到目前为止我们编写的程序是一个单线程作为应用程序的运行实例的单一的过程运行的。但是,这样子应用程序同时只能执行一个任务。为了同时执行多个任务,它可以被划分为更小的线程。

C#基础知识点个人整理【菜鸟教程】相关推荐

  1. 【信息系统项目管理师】第2章-信息系统项目管理基础 知识点详细整理

    个人资料,仅供学习使用 教程:信息系统项目管理师(第3版) 修改时间--2021年9月11日 18:11:23 参考资料: 信息系统项目管理师(第3版) 题目书(2021下半年)--马军 本文包括: ...

  2. 基础编程-学习网站-菜鸟教程

    菜鸟教程-各色各类的基础编程资料,很充实很详细,值得推荐!同时也值得当作手册查阅.

  3. Python零基础入门,纯干货!【Python基础知识点汇总整理】

    目录 第一章 认识Python.Python常用集成开发环境PyCharm 一.认识 Python 01. Python 的起源 1.2 Python 的设计目标 1.3 Python 的设计哲学 0 ...

  4. 操作系统部分基础知识点手动整理

    有道云笔记https://note.youdao.com/s/9gZUOB0J (乱序.自取) 第一章: 1.操作系统定义:管理系统资源.控制程序执行.改善人机界面.提供各种服务,并合理组织计算机工作 ...

  5. Android基础知识点的整理3

    请描述一下Broadcast Receiver. 定义:接收自己或其他App发送的Broadcast 好处:群发消息 使用:code  XML 广播分类:无序.有序 回答问题的思路: 是什么 功能/作 ...

  6. 大一python考试知识点_Python基础知识点(精心整理)

    Python 中的变量赋值不需要类型声明. 每个变量在内存中创建,都包括变量的标识,名称和数据这些信息. 每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建. 等号( = )用来给变量赋值. 等 ...

  7. java基础思维导图-菜鸟教程

  8. 调音台docker教程_[整理]菜鸟教程:docker使用笔记

    - docker # 查看 docker stats 指令的具体使用方法 - docker stats --help # 运行一个web应用 - docker pull training/webapp ...

  9. Python教程分享之Python基础知识点梳理

    Python语言是入门IT行业比较快速且简单的一门编程语言,学习Python语言不仅有着非常大的发展空间,还可以有一个非常好的工作,下面小千就来给大家分享一篇Python基础知识点梳理. Python ...

最新文章

  1. python对文件的读操作方法有哪些-python--文件的读写操作
  2. python json.loads()中文问题-python处理json数据中的中文
  3. 通过SSH克隆远程仓库(GitLab)到本地
  4. MySQL深入(一)
  5. linux如何映射Windows下的磁盘为网络盘
  6. 【渝粤题库】广东开放大学 经济学基础 形成性考核
  7. 增效工具_【危中寻机】降本增效生存之道 运用IE基础工具提升制造效率
  8. android 使用 audiorecord 和 audiotrack 实现实时录音播放
  9. php判断是不是纯汉字,php判断输入是否是纯数字,英文,汉字的方法
  10. 论文都看不懂,你还搞什么人工智能?
  11. 数学建模--层次分析法
  12. displaytag 国际化 探索日志 注释
  13. 创意信息联席CTO:学习财务思维,打造100位技术大咖
  14. MSN 与六度分隔理论(转)
  15. 业务流程优化与信息化到底有多远?
  16. Oracle 误删恢复
  17. WPF无边框窗体拖动
  18. 荣联 云通讯 发送短信通知 node
  19. 东莞蒙德服务器维修,蒙德驱动器变频器维修常见报警:OC1 OC2 OC3 OC4
  20. 前端学习——Mobx

热门文章

  1. Android 微信抢红包插件
  2. Python KPM算法
  3. 拿番茄炒鸡蛋来讲解一下大数据项目的流程
  4. Spring之ApplicationContext介绍
  5. Scikit-learn机器学习实战之Kmeans
  6. asterisk拨号计划中Hangup() App执行规则
  7. java中汉字自动转换成拼音
  8. python“反反爬虫”
  9. Linux 安装Oracle11g完整安装图文教程另附基本操作 (分享)
  10. neo4j的搭建和实例使用