C#概念
- 类型
- 笔记
- 知识点:
- 1. 值类型(储存在栈)和引用类型(储存在堆)的存储
- 2. 栈和堆:
- 3. 构造函数:
- 4. 重载方法:参数(签名)数量、类型不同
- 5. 重写方法:子类重写(override)父类的虚方法(virtual)
- 区别
- 6. 多态:用重载实现(函数重载和运算符重载)
- 7. 虚方法:有实体可被子类重写
- 8. 抽象方:
- 9. 类型转换:
- 10. object类型:赋给object的值必须作为引用类型,并存放在托管堆中
- 11. dynamic类型:
- 12. lambda表达式(优化代码):简化委托的匿名方法
- 13. 枚举器:让类可枚举
- 14. 迭代器:设计模式中的行为模式,能够获取到序列中的所有元素而不用关心是其类型
- 15. LINQ:查询方法
- 16. XML(可扩展标记语言):是存储和交换数据的重要方法
- 17. 异步编程:
- 18. 进程、线程、协程:
- 19. 线程池:
- 20. 多线程编程:
- 21. 缓存:
- 22. 异常处理:
- 23. 不安全代码:
- 24. 文件的输入与输出: FileStream 类
- 25. 释放资源:
- 26. 预处理指令:指示编译器如何处理源代码
- 27.反射:
- 28.元数据:
- 29.Type类(反射中最重要的类型):
- 30.特性:将一些信息与程序元素关联(java annotation)
- 31.正则表达式:
- 关键字/运算符:
- 名词:
- 杂记:
类型
成员类型:
- 字段:一个语句;成员(类、结构)
- 属性:两个语句(get;set);(类、结构)
- 方法:多个语句;成员(类、结构、接口)
- 变量:方法的成员,只在自己的大括号内有效
- 索引器:让类可索引,既索引方法,方法体内定义get{}、set{},使方法的调用可写成实例的索引a[ ]
- 事件:成员,简单委托(封装委托),可给事件增添委托实例(多个方法);包含多个方法;流程:声明委托,发布事件,触发事件event(),订阅事件(給事件加方法),声明方法。
用户定义类型:
- 类:多个方法;引用类型
- 结构:多个方法(与类相似);值类型;减少内存管理开销
- 接口:未实现的函数成员的集合;多个方法(无内容),在实现类中补充内容;使同一方法可以使用不同类型数据;调用时(接口名.方法名)
- 委托:引用类型;包含多个方法(调用表),且按顺序执行
- 数组:存储相同类型数据的
- 枚举:枚举定量
- 泛型:类class a < T >;方法void aaa<T1 ,T2> (T1 t1, T2 t2){} ;可不固定类型,传入多种类型
笔记
知识点:
1. 值类型(储存在栈)和引用类型(储存在堆)的存储
2. 栈和堆:
①栈存储的数据:值类型变量的值;程序当前的执行环境;传递给方法的参数;
②堆存储引用类型变量的值;堆可以任意顺序存入和移除;CLR的自动垃圾收集器(GC),自动清除无主的堆对象;
3. 构造函数:
初始化实例对象(new了就有),有参无参,显式隐式
class Class2
{
int q = 1;
public Class2()
{
Console.WriteLine(q);
}
public Class2(string b)
{
Console.WriteLine("bbbb");
}
}
class Class3:Class2
{
public Class3()
{
Console.WriteLine("ee");
}
public Class3(string a):base("1111")
{
Console.WriteLine(a);
}
}
Class3 AA =new Class3("aaaa");
--------------------------------------------
输出:
bbbb
aaaa
4. 重载方法:参数(签名)数量、类型不同
5. 重写方法:子类重写(override)父类的虚方法(virtual)
区别
①重载是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数。
②覆盖(也叫重写)是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即函数名和参数都一样,只是函数的实现体不一样。
6. 多态:用重载实现(函数重载和运算符重载)
7. 虚方法:有实体可被子类重写
8. 抽象方:
①抽象方法:无实体(抽象出的东西不确定);必须在抽象类中;必须被子类重写
②抽象类:不能实例化,有不确定的东西,实例化子类
9. 类型转换:
①隐式转换:低位到高位转换,不丢数);
②显式转换又称强制转换:(目标类型a)源类型b
;
③装箱 :把“值类型”转换成“引用类型”(Object);创建一个值得引用副本;
④拆箱 :把“引用类型”(Object)转换成“值类型”;装箱可隐可显,拆箱不能隐式
;
⑤用户自定义转换
public static implicit/explicit operator int(preson p) { return p.Age; }
10. object类型:赋给object的值必须作为引用类型,并存放在托管堆中
11. dynamic类型:
①使用动态语言编写的程序集时使用(c#和java是静态语言,python是动态)
②dynamic被编译后是一个Object类型
12. lambda表达式(优化代码):简化委托的匿名方法
x => x%2 = 1;//取奇数
delegate void mydel(int x)/mydel() ;
mydel del = delegate(int x){return x+1;};//匿名方法
mydel del = x => {return x+1;};//lambda表达式
mydel del = () => {return x+1;};//lambda表达式
13. 枚举器:让类可枚举
①枚举器知道项的次序并且跟踪它在序列中的位置,依次返回请求的当前项
②enumerator枚举器;enumrable可枚举类型
③IEnumerator接口:包含3个函数成员:Current(返回当前位置的项)、MoveNext(前进位置到下一项;返回位置有效,方法返回ture,否则则false),Reset(位置重置到原位置)
④IEnymerable接口:实现IEnymerable接口的类是可枚举类,实现GetEnumerator()方法的类型使可枚举类型;包含一个GetEnumerator()方法,返回对象的枚举器。
14. 迭代器:设计模式中的行为模式,能够获取到序列中的所有元素而不用关心是其类型
①更简单的创建枚举器和枚举类型
②yield return指定返回的下一项;yield break 序列中没有其他项了,跳出
15. LINQ:查询方法
①方法语法:类似方法有标准查询运算符文档;
var count = intArray.Count();//扩展语法
var count = Enumrable.Count(intArray)//方法语法
①查询语法:与SQL语句相似
var a = from n in numbers1
join m in numbers2 on n.ID equals m.ID
into number1and2 //查询延续
from nm in number1and2 //找出的是1、2重叠项
let sum = n + m ;
where n < 20
select n;
from student in students
orderby student.age //以age排序
group student by student.Major //以主修科目分组
select student ;
select new {s.Name, s.Age, s.Major};//查询中的匿名类型
var b = unmbers.where(x => x < 20);//lambda表达式(委托匿名方法)做参数
var c = (from n in numbers
where n < 20
select n).Count();
16. XML(可扩展标记语言):是存储和交换数据的重要方法
①XML文档中的数据包含了一个XML树,它主要由嵌套元素组成
②LINQ对XML的操作有两种:
<1>LINQ to XML API由很多表示XML树组件的类组成,有3个重要的类:XElement(元素)XAttribute(属性)XDocumen(文档),用来创建XML文档
<2>用LINQ查询方法来查询XML文档
17. 异步编程:
- 避免线程堵塞,但不开启新线程,不用CPU:
①异步主要应用于IO操作,数据库访问,磁盘操作,Socket访问、HTTP/TCP网络通信
②不用CPU时:拥有DMA(直接内存存取)功能的硬件和
内存进行数据交换不消耗CPU资源。CPU在发起传输时发送一个指令,硬件就开始自己和内存交换数据,在传输完成后硬件触发一个中断来通知操作完成。这些无须消耗CPU时间的I/O操作正是异步操作的硬件基础。所以即使在DOS磁盘操作系统”,DOS主要是一种面向磁盘的系统软件,命令行DOS命令
这样的单进程而且无线程概念
系统中也同样可以发起异步的DMA操作
③在硬件中,硬盘、网卡、声卡、显卡等都有DMA功能。CLR所提供的异步编程模型就是让我们充分利用硬件的DMA功能来释放CPU的压力 - 使用了 async 修饰符的方法称为异步方法,通常配合 await 运算符和 Task 异步任务一起使用。
- Task 分为两种:
1)Task,表示可以执行一个异步操作
2)Task,表示可以执行带有返回值的异步操作 - 异步方法的返回类型必须为 void、Task、Task 中的其中一种。
归纳一下:void 不关心结果;Task 只关心是否执行完成;Task 不止关心是否执行完成,还要获取执行结果。
//异步方法调用
CommandDropLitter();//void
Task task = CommandDropLitter();//Task
Task<string> task = CommandDropLitter();//Task<TResult>
//取消要借助 System.Threading.CancellationTokenSource和System.Threading.Tasks.CancellationToken对象来完成
//取消实例化
CancellationTokenSource source = new CancellationTokenSource();
//注册取消时的回调委托
CancellationTokenSource source = CancellationTokenSource.CreateLinkedTokenSource(source.Token);
source1.Token.Register(() =>{Console.WriteLine("这是因为);});
//取消
source.Cancel() ;
source.CancelAfter(300); //方法到达指定时间后为 true
//建立异步方法
public async void CommandDropLitter()
{
Console.WriteLine("这时我准备去扔垃圾,线程Id为:{0}", GetThreadId());
await Task.Run(() =>
{
Console.WriteLine("屁颠屁颠的去扔垃圾,线程Id为:{0}", GetThreadId());
Thread.Sleep(1000);
});
Console.WriteLine("垃圾扔了还有啥吩咐,线程Id为:{0}", GetThreadId());
}
使用异步Lambda表达式
startworkButton.Click += async ( sender, e ) =>
{
SetGuiValues(false, "work started")
await DoSomework();
SetGuiValues(true, "work finished")
}//将Lambda表达式注册到按钮点击事件中
18. 进程、线程、协程:
①进程是操作系统资源分配的基本单位(应用程序运行的载体),而线程是任务调度和执行的基本单位(程序执行流的最小单元,程序中真正的执行者)
②线程分为前台线程和后台线程,用户线程就是前台线程,守护线程就是后台线程,线程创建时不做设置默认是前台线程;
前台进程与后台进程的区别:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。
③协程:协程的粒度比线程更小,协程类似子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。这个中断去执行其他子程序,不是函数调用,有点类似CPU的中断
19. 线程池:
①线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。
②线程池可以看做容纳线程的容器;一个应用程序最多只能有一个线程池;ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池;每排入一个工作函数,就相当于请求创建一个线程;
③线程池的作用:多线程最大的问题在于“线程的调度”,而在.NET中引入了线程池的概念,避免人为创建多余线程;线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务;线程池中的线程不能人为控制,开始、挂起、终止
20. 多线程编程:
目的:1)吞吐量:一个请求一个线程(如struts2,是多线程的,每个客户端请求创建一个实例,保证线程安全),或多个请求一个线程,如果是单线程,那只能是处理一个用户的请求。
2)伸缩性:通过增加CPU核数来提升性能。
作用:避免线程阻塞,用到CPU(例:从数据库读取数据耗时、耗CPU)
四种开启线程的方法:异步委托、通过thread类、通过线程池、通过任务:1>Task 2>TaskFactory (资料连接)
//多线程
Thread th1 = new Thread(new ThreadStart(方法)); //固定写法
Thread th2 = new Thread(new ThreadStart(Run2));
Thread th3 = new Thread(new ThreadStart(Run3));
th1.Priority = ThreadPriority.Highest; //设置优先级
th2.Priority = ThreadPriority.AboveNormal;
th3.Priority = ThreadPriority.Normal;
th1.Name = "aa"; //设置名字
th2.Name = "bb";
th3.Name = "cc";
th1.Start(); //启动线程
th2.Start();
th3.Start();
//线程池
for (int i = 0; i < 10; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Run1), i);
}
21. 缓存:
(引用资料)
①缓存就是数据交换的缓冲区;缓存尽量在数据量小、重复查询量大的情况下使用。因为缓存也是要耗内存的,服务器内存是有限的!
②应用:
1)微软自带的类库System.Web.Caching
2)自己写缓存操作方法(CacheHelper)
①构造一个字典型容器,用于存放缓存数据
②构造三个方法(添加数据至缓存容器、从缓存容器获取数据、判断缓存是否存在)
22. 异常处理:
try
{
为避免异常而被保护的句子;
throw 对象名;
}//抛出异常后try内异常之后的句子不执行
catch
catch(异常类名称)
catch(异常类名 对象)
{
try抛出的异常的处理程序;
throw;
}//没找到处理程序去上一层找,然后回到这一层执行finally,在执行上一层finally,再继续执行
finally
{
无论try有没有抛出异常都要执行的代码;
}
23. 不安全代码:
当一个代码块使用 unsafe 修饰符标记时,C# 允许在函数中使用指针变量。不安全代码或非托管代码是指使用了指针变量的代码块。
static unsafe void Main(string[] args)
{
int var = 20;
int* p = &var;
}
24. 文件的输入与输出: FileStream 类
FileStream F = new FileStream("test.dat",FileMode.OpenOrCreate, FileAccess.ReadWrite);
25. 释放资源:
(引用资料)
①GC(不能自动释放非托管资源)只能释放托管资源,人为GC.Collect()强制执行
②Finalize只释放非托管资源,用析构函数(由GC调用)
③Dispose模式(需要实现IDisposable接口)释放托管和非托管资源,void Dispose(bool disposing)函数通过一个disposing参数来区别当前是否是被Dispose()调用。vs可选择一段代码,然后自动生成dispose模式
class A
{
public A()//构造函数
{
Console.WriteLine("Creating A");
}
~A()//析构函数
{
Console.WriteLine("Destroying A");
}
}
class B:A
{
public B()
{
Console.WriteLine("Creating B");
}
~B()
{
Console.WriteLine("Destroying B");
}
}
class C:B
{
public C()
{
Console.WriteLine("Creating C");
}
~C()
{
Console.WriteLine("Destroying C");
}
}
class App
{
public static void Main()
{
C c=new C();
Console.WriteLine("Object Created ");
Console.WriteLine("Press enter to Destroy it");
Console.ReadLine();
c=null;
//GC.Collect();
Console.Read();
}
}
---------------------------------------------------------------------------------------------------
析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),
系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,
会自动调用析构函数后释放内存)。构造函数与析构函数调用顺序不同
Creating A
Creating B
Creating C
Object Created
Press enter to Destroy it
Destroying C
Destroying B
Destroying A
---------------------------------------------------------------------------------------------------
//一旦使用完对象你就想释放资源,dispose模式
public class ResourceHolder : IDisposable
{
private bool isDisposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!isDisposed)
{
if (disposing)
{
// Cleanup managed object by calling their Dispose() method
}
// Cleanup unmanaged objects
}
isDisposed = true;
}
~ResourceHolder()
{
Dispose(false);
}
public void SomeMethod()
{
// Ensure object not already disposed before execution of any method
if (isDisposed)
{
throw new ObjectDisposedException("ResourceHolder");
}
// Method implementation
}
}
//using代码块
using (MyClass objCls =new MyClass())
{
}
---------------------------------------------------------------------------------------------------
当控制从using块通过成功运行到结束或者抛出异常退出时,MyClass的IDispose.Dispose()将会被执行。
记住你例示的对象必须实现System.IDisposable接口。using语句定义了哪个对象将被清除的一个范围。
26. 预处理指令:指示编译器如何处理源代码
#define DEBUG
#define VC_V10
using System;
public class TestClass
{
public static void Main()
{
#if (DEBUG && !VC_V10)
Console.WriteLine("DEBUG is defined");
#elif (DEBUG && VC_V10)
Console.WriteLine("DEBUG and VC_V10 are defined");
#else
Console.WriteLine("DEBUG and VC_V10 are not defined");
#endif
Console.ReadKey();
}
}
#region my 和 #endregion //把一段代码标记为有给定名称的一个块
#if DEBUG && RELEASE
#error "You've defined DEBUG and RELEASE simultaneously!" //指出错误
#endif
#warning "Don't forget to remove this line before the boss tests the code!"//指出警告,或提示未做工作
#line 164 "Core.cs" // 更改错误列表中,文件名和行号
#line default // 恢复默认行号
#pragma warning disable // 取消警告
public class MyClass
{
int neverUsedField; // 编译整个 MyClass 类时不会发出警告
}
#pragma warning restore // 恢复警告
27.反射:
一个运行的程序查看本程序或其他程序的元数据的行为叫做反射
28.元数据:
①描述数据的数据
如:书的作者、出版社等,既数据的描述
如:有一条学生信息记录,其中包括字段姓名(name)、年龄(age)、性别(male)、班级(class)等,那么name、age、male、class就是元数据。(如类的成员:字段、属性、方法)
②元数据的管理:类似图书馆的目录
29.Type类(反射中最重要的类型):
①Type类是抽象类(不能有实例),Type对象能让我们获取程序使用的类型的所有信息(包含类型的特性)
②获取Type对象:1) object类的GetType()方法; 2)typeof运算符
③可利用反射查看某种Type下的方法,属性,字段和支持的接口等。
using System.Reflection; //反射
namespace ConsoleApplication6
{
class myclass
{
public int Field1;
public int Field2;
public void Method1() { }
public int Method2() { return 1; }
}
class Program
{
static void Main(string[] args)
{
Type t = typeof(myclass); //获取Type对象
myclass my = new myclass();//获取类的对象
Type tt = my.GetType(); //获取Type对象,同typeof
FieldInfo[] ff = t.GetFields();
MethodInfo[] mm = t.GetMethods();
foreach (FieldInfo f in ff)
Console.WriteLine("Field:{0}", f.Name);
foreach (MethodInfo m in mm)
Console.WriteLine("Method:{0}", m.Name);
}
}
}
-------------------------------------------------------------
Field:Field1 //字段
Field:Field2 //字段
Method:Method1 //方法
Method:Method2 //方法
Method:Equals //基类方法
Method:GetHashCode //基类方法
Method:GetType //基类方法
Method:ToString //基类方法
30.特性:将一些信息与程序元素关联(java annotation)
①一种允许我们向程序的程序集增加元数据的语言结构
②特性用于保存程序结构的信息的一个特殊类型的类
//全局特性,一般放置在AssemblyInfo.cs,通常包含公司、产品和版权信息的元数据
[assembly: MyAttribute("This is a demo", "Version 1.3")]//把特性设置在程序集级别
[AttributeUsage(AttributeTargets.Method|AttributeTargets.Constructor)]//指定特性可用于方法和构造函数
public sealed class MyAttributeAttribute : System.Attribute//自定特性
{
public string Description{get;set;}
public string VersionNumber;
public MyAttributeAttribute() { }//无参构造函数
public MyAttributeAttribute(string desc, string ver)//有参构造函数
{
Description = desc;
VersionNumber = ver;
}
}
[MyAttribute("This is a demo", "Version 1.3"), Serializable]//使用有参构造函数,多个特性(serializable指示一个类可以序列化)
[MyAttribute(Description = "This is a demo", VersionNumber = "Version 1.3")]//使用无参构造函数
class Program
{
static void Main(string[] args)
{
[MyAttribute("hello")]//特性的构造函数
myclass my = new myclass("hello");//类的构造函数
Type t = my.GetType();//获取Type对象,同typeof
bool isDefined = t.IsDefined(typeof(myclass), false);//访问特性,检测特性是否应用到类上
object[] Attarr = t.GetCustomAttributes(false);//访问特性,返回应用到结构的特性的数组 //利用反射查看特性
foreach (Attribute a in Attarr)
{
MyAttributeAttribute attr = a as MyAttributeAttribute;//返回对象是object数组,用as强转换为相应数组
if (null != attr)
{
Console.WriteLine(attr.Description);
Console.WriteLine(attr.VersionNumber);
Console.ReadKey();
}
}
}
31.正则表达式:
①处理文本;本质是是使用一系列特殊字符模式来表示某一类字符串
②使用:匹配方法和验证方法
③在 C# 语言中使用正则表达式时要用到 Regex 类, 在System.Text.RegularExpressions 命名空间中
④正则表达式的符号主要分为元字符和表示重复的字符(如: \d{15}|\d{18} 验证身份证号码(15位或18位))
关键字/运算符:
- is运算符:判断一个对象是否可以转换为指定的类型,返回bool值:
- as运算符:与强制转换类似,转换失败返回null,通常搭配判空操作使用(判断转换是否成功)
- this关键字:
①表示类的实例(成员)对象(类的里面方法的外面的成员);
②串联构造函数(一个构造函- - 数调用其他构造函数;以参数最多的构造函数为主函数,其他均调用使用,易于管理);
③添加扩展方法;
④索引器 - var关键字:var a = new class1 ();
- operat关键字:
①重载运算符;
②类或结构中类型的自定义转换 - checked和unchecked关键字:类型转换的溢出检测,unchecked不检测,checked检测,若溢出则抛出异常
- using关键字:
①using指令:using 命名空间;using 别名=命名空间;
②using方法(异常及close功能)
using(person p = new person())
{
Console.Write(p.age);
}
//try
{
person p = new person();
}
//finally
{
Dispose of p (Dispose关闭连接,清理连接所占用的资源)
}
- private(默认):同一类或结构中可访问
public:同一程序集或引用该程序集的其他程序集的任何位置都可访问
protected:同一类、结构或子类可访问
internal:同一程序集的任何位置都可访问,但其他程序集不可以 - sealed关键字:用来修饰类和方法
①修饰类表示此类不能被继承
②修饰方法时,表示该方法不能被重写 - ref关键字:参数通过引用来传递;形参前加out,该参数就会成为一个实参的一个引用,而不再是一个实参的一个副本;要求变量必须在传递之前进行初始化; 通常向方法传递一个实参时,对应的形参会用实参的一个副本来初始化
- out关键字: 与ref类似,变量传递之前可不用初始化
名词:
- 句柄:
①句柄是WONDOWS用来标识被应用程序所建立或使用的对象的唯一整数。
②从数据类型上来看它只是一个16位的无符号整数。应用程序几乎总是通过调用一个WINDOWS函数来获得一个句柄,之后其他的WINDOWS函数就可以使用该句柄,以引用相应的对象。
③句柄地址(稳定) → 记载着对象在内存中的地址 ────> 对象在内存中的地址(不稳定) → 实际对象 (因为操作系统的虚拟内存技术,内存管理器经常在内存中来回移动对象,对象地址不稳定) - CIL(通用中间语言):
C#等 ==> CIL ==>机器码,使用中间语言是夸平台跨语言操作方便 - (1)**托管资源:**一般是指被CLR(公共语言运行库,有一项服务GC垃圾收集器)控制的内存资源,这些资源的管理可以由CLR来控制,例如程序中分配的对象,作用域内的变量等。
(2)**非托管资源:**是CLR不能控制或者管理的部分,这些资源有很多,比如文件流,数据库的连接,系统的窗口句柄,打印机资源 等,这些资源一般情况下不存在于Heap(内存中用于存储对象实例的地方)中。 - **对象浏览器:**VS视图->对象浏览器(查看各程序集各级信息及成员)
- 序列化:
①使用来解析对象和构建对象的。通常对象都是存在于内存中的如果我们想在远程(socket传输、或者持久化到存储数据库或文件系统中)拿到这个对象,那就要把这个对象变成一种可描述的形式进行传输,这就是序列化。反序列话就是我们拿到了关于一个对象的描述,在把他转化成内存中的对象,这就是反序列化过程。
②常用的有二进制序列化和xml序列化。 - 缓冲区:
又称为缓存,它是内存空间的一部分。是在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。
作用:比如我们从磁盘里取信息,我们先把读出的数据放在缓冲区,计算机再直接从缓冲区中取数据,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度。
缓冲区分为三种类型:全缓冲、行缓冲和不带缓冲。 - ASCii(英语、西欧) GB2312(中文简体)GBK(中文扩展繁体、日、韩) BIG5(中文繁体)Unicode(统一码、至少需要两字节)UTF-8(对unicod的实现,一种变长的编码方式。可以使用1~4个字节表示一个符号)UTF-16、UTF-32
杂记:
- 代码移动:向右:TAB键 ;向左:SHIFT+TAB键
- string类:string.Length(Concat、Contains、Format、Insert等),字符串不能被修改,改变字符串后返回了新的副本
- StringBuilder类:动态、有效的产生字符串,避免创建副本;输出字符串时 .ToString
- 可空类型:
int? a = null; //可空值类型
int b = (int)a; //int?转换为int
int c =a ?? -1; //返回-1;空接合运算符,第一个操作数运算后为null,第二个操作数被返回
a = 10;
c = a ?? -1; //返回10
mystruct? my = new mystruct(); //可空结构类型
- Main方法:
static void Main(){...} //不返回值给执行环境
static void Main(string[] args){...} //命令行参数
static void Main(){...} //返回int值报告程序的成功和失败,0通常用于表示成功
static void Main(string[] args){...} //命令行参
- 文档注释:/// … /// ;XML元素,项目属性面板中可生产此XML文档
- 嵌套类型:
①嵌套类隐藏得比较深,且有权限访问所在类的一切成员,无论是私有的还是公有的。
②嵌套类主要用于当该类仅仅被所在类使用,不需要外部进行显式地构造,且需要对所在类的成员进行大量访问操作的情况。 - 字段转属性:control+R,E
- 多行注释:control+K,C ;取消control+K,U
- 窗体、lable等隐藏(名称.Visable = false;)
- WPF:GUI设计与业务逻辑剥离;XAML(可扩展应用程序标记语言)它在做桌面开发和媒体网络程序开发中扮演HTML+CSS+JS的角色,成为设计师和程序员沟通的枢纽,在WPF中用作GUI设计。
- WPF无法将 lambda 表达式 转换为类型“System.Delegate”,因为它不是委托类型的解决方法:
①当我们打开一个WPF应用程序即开启了一个进程,该进程中至少包含两个线程。一个线程用于处理呈现:隐藏在后台运行;一个线程用于管理用户界面:接收输入、处理事件、绘制屏幕以及运行应用程序代码。即UI线程。
②WPF中的UI控件,他们都是从DispatcherObject继承,所以都必须由UI线程进行调度和使用,如果我们在其他的后台线程中操作界面相关的元素时,就会出现如下的异常信息:调用线程无法访问此对象,因为另一个线程拥有该对象。
在 WPF 中,只有创建 DispatcherObject 的线程才能访问该对象。 例如,一个从主 UI 线程派生的后台线程不能更新在该 UI 线程上创建的 Button 的内容。 为了使该后台线程能够访问 Button 的 Content 属性,该后台线程必须将此工作委托给与该 UI 线程关联的 Dispatcher(调度者)。使用 Invoke(调用) 或 BeginInvoke 来完成此操作。 Invoke 是同步操作,而 BeginInvoke 是异步操作。 该操作将按指定的 DispatcherPriority 添加到 Dispatcher 的事件队列中。
//MethodInvoker(方法调用者),是一个委托
//Invoke 是同步操作,而 BeginInvoke 是异步操作。
Invoke(new MethodInvoker(delegate { Text = "test"; }));
Invoke(new MethodInvoker(() => Text = "test"));