C#基础
-
Object
object
是引用类型,但是值类型可以转换为object
类型,object
类型也可以转换为值类型,但是转换的过程就产生了装箱或拆箱的操作。装箱:值类型转换为引用类型
拆箱:引用类型转换为值类型
在
Object
的扩展方法中包含Equal
方法和常用的“==
”还有有区别的,假如对比的是值类型 则对比的是两个参数的值是否相等,
Equal
和==
是没有区别的,因为值类型存储在栈中,所以对比是相等的。假如对比的是引用类型 则存在区别,
==
对比的是两个值得地址,Equal
则对比的是存的值是否相等,因为引用类型是存储在 堆中的,两个对比的参数,值相等,但是分配完成第一个参数后,第二个参数会直接分配内存中的地址指向已存在的值,不会再重新开辟空间。ReferenceEquals
是object
的静态方法,对比的是两个值的引用是否相等。
例子:
例子1:
string aa=new string("12");
string bb=new string("12");
aa==bb //false
aa.Equal(bb);//True
例子2:
string a1="11";
string a2="11";
a1=a2//true
a1.Equal(a2);//true
-
GetType
和Typeof
的区别:GetType
和Typeof
作用是相同的都是返回使用类型的Type
类型。Typeof
是运算方法,平时使用中会得到一个Class
的Type
GetType
是来源于System.Object
类型,所以需要初始化之后才能使用,会得到一个 实例 后的Type
-
值类型和引用类型
值类型:分配在栈上,保存的是值,每次都会创建一个
引用类型:分配在堆上,创建两个相同的值,其实际只有一个值,两个内存地址,指向同一个值。
两个类型的互相转换即为:装箱/拆箱,同类型的转换不算装箱/拆箱
-
面向对象:封装(内部实现细节与外部展示分开) 继承 多态
C#共同基类
Object
类与接口 class和
Interface
类型安全:
静态类型:
Static Typing
动态类型:
dynamic
强类型:
Strongly Typed language
内存管理:CLR 公共语言运行时 GC 自动垃圾回收
隐式转换:编译器保证信息不回丢失 .。比如:
int
转换为long
类型,显示转换:编译器不能保证信息会丢失。比如:
long
转换为int
类型,(因为long
比int
长)Using static system
这样的引用方式 表明system
下所有的静态成员不需要 写前面部分直接使用方法签名:就是指方法的名字,或者方法参数的名字
泛型:
where T :base-class
某个父类的子类where T :interface
实现了接口where T :Class
必须是class
类型where T :Struct
值类型where T :new()
必须有一个无参构造函数where u :T
U
继承T
函数协变 :当一个值作为返回值
out
public Interface IEnumerable<out T>
逆变 :当值作为输入
public delegate void Action<in T>
不变 :当值作为输入又作为输出
public Interface IList<T>
Task和Thread得区别
:Task
使用的线程池,主线程结束后,子线程就已经结束了。Thread
类主要用于实现线程的创建以及执行。Task
类表示以异步方式执行的单个操作。1、
Task
是基于Thread
的,是比较高层级的封装,Task
最终还是需要Thread
来执行2、
Task
默认使用后台线程执行,Thread
默认使用前台线程3、
Task
可以有返回值,Thread
没有返回值4、
Task
可以执行后续操作,Thread
不能执行后续操作5、
Task
可取消任务执行,Thread
不行6、
Thread
在父方法上获取不到异常,而Task
可以。
C#中的异步可以简单的用async
和 await
配合来实现,使用异步的函数,在没有调用await
前,还是按顺序单线程执行的,当运行到await
的时候,系统才会异步调用其他的方法来运行,如果没有await
, 函数就是同步按顺序的运行。所以,await
才是异步中的关键部分,在await
范围内的代码,是多线程方式运行的,可以将需要异步处理的代码放在await
中运行,或者简单的用一个Task.Delay
来延时,以达到异步切换代码运行的效果。await
后面接的是一个Task
, 每一个Task
在运行时,由系统的Task
池来分配,以实现异步的功能。
这里再来说说用aysnc
和直接用thread
的区别,其实简单来讲,就是效率的问题,async
用的线程池,在await
中运行的代码是由线程池分配的线程,根据系统的任务,自动分配和释放,而用 new thread
的方法,通常是需要手动控制的。很显然,在处理一些短时间,且对运行的时间性和稳定性不是特别严格的问题时,用async
会很有优势,但是对于一些在后台需要长时间稳定运行的程序,用thread
会更好
C#扩展方法
扩展方法是指对代码现有类型的添加,不需要创建新的派生类型。在.net4
版本中提出的,
扩展方法是对现有类型的添加,所以必须要有一个类型,比如需要添加一个string类型的方法,那么扩展方法的参数就是string类型。
扩展方法也是方法,则需要一个类单独去写扩展方法,这样的类有两点注意:
-
需要顶级是静态方法。
-
对客户代码有足够的权限。
-
扩展方法的参数必须要以 this 头
public static class StringExtentsion {
public static bool IsEmpty(this string str)
{
return string.IsNullOrWhiteSpace(str);
} }
class Program
{
static void Main(string[] args)
{
string[] arr = new string[] { null, string.Empty, " ", " \t ", " \r\n " };
foreach (string str in arr)
{
bool result = str.IsEmpty();
Console.WriteLine(result); // 编译通过,运行无异常,并且全部输出True
}
Console.Read();
}
}