类中的this和base
1.this可以用来查看类里面的方法和字段
2.base可以用来查看父类中的方法和字段
虚函数、抽象类、接口
当把类中的函数定义为虚函数(virtual)的时候,可以在子类中对虚函数进行重写,如果子类进行了重写(override)则派生类实例化调用的是子类的函数方法,如果没有进行重写调用的则是父类的方法,重写后父类的方法没有了。
抽象类的函数方法为抽象方法(abstract),当派生类对父类中的方法一定会重写的时候,就没有必要将父类方法定义为虚函数,而直接定义为抽象类。
接口(interface),接口中的方法不能进行定义,接口中不能包含字段,当一个类继承接口的时候需要对接口中的所有方法进行实现,接口可以继承,当A接口继承B接口后,继承A接口的类要同时对A和B接口中的方法进行实现。
stringBuilder和string的区别
string内容不可改变,stringBuilder可以频繁的进行改变
Action和Func
Action和Func是两个委托,Action表示参数为int,无返回值得方法类型,如:
static void set(int){}
Action<int> a = set;
Func表示有返回值和参数的委托,当有返回值时,最后一个参数表示返回值类型,剩余参数表示参数类型,必须有返回值类型如:
static string set(int,int){}
Func<int,int,string> b = set
使用委托解决冒泡排序中的类型适用问题
假设有冒泡排序sort(int array[]){},示例如下:
//比较的类型employee
class employee{
private string name{get;private set;}
private int age{get;private set;}
static bool Compare(employee a,employee b){
return a.age<b.age}
}
//适用于比较employee的冒泡排序
static void commonsort<T>(T[]sortArray,Func<T,T,bool> method){}
//使用时
commonsort(Employee[],employee.Compare){}
多播委托
一个委托指向多个方法,假设委托的方法有返回值,多播委托只能调用最后添加的方法的返回值的结果,一般将多播委托设为无返回值;
如果多播委托中一个方法抛出异常,停止
//方法1
static void method1(){}
//方法2
static void method2(){}
Action a=method1;
a+=method2;
Delegate[] delegate = a.GetInvocationList() //调用该方法能得到所有方法的列表
匿名方法
当某一个方法并不需要在其他地方调用的时候,直接将方法的定义赋给一个委托,需要使用delegate关键字
Action<int,string> a=**delegate**(int a,string b){}
lambda表达式
lambda表达式:
Func<int,int> a = (arg1,arg2)=>
{
return arg1+arg2
}
//当参数只有一个的时候不需要加括号
Func<int,int> test = a=>a+1
事件
事件event的声明只能放在类里面,在类里面声明一个委托类型的变量。
事件是类或对象向其他类或对象通知发生的事情的一种特殊签名的委托
//猫抓老鼠的例子
class cat{
private string name;
private string color;
public cat(string name,string color){
this.name = name;
this.color = color;
}
public void catcoming(){
Console.Writeline(color+"颜色的猫"+name+"来了")
if(catcome)
catcome()//调用事件,该事件里注册了很多订阅者的方法
}
**public event Action catcome**;//定义了一个委托类型的事件,如果不适用event修饰,则可以在类的外部通过对象调用访问,这样是不可以的,定义这样一个事件的目的是为了产生一个订阅/发布的机制,这样在订阅者那里可以通过注册该事件,达到订阅的目的。
}
//老鼠,订阅者
class mouse{
private string name;
private string color;
public void mouse(string name,string color, cat cats){
this.name = name;
this.color = color;
cats.catcome+=this.runAway;//注册
}
public void runAway(string name,string color){
Console.Writeline(..........);
}
}
LINQ联合查询
假设有materlist和kongfulist两个list表,需要对其中的数据进行查询,方法:
//method 1
var res=from m in materlist
from k in kongfulist
where m.kongfu==k.name && m.power>90
select m //返回m
select new{master = m, kongfu = k}//先建两个对象master和kongfu,生成联合对象res
//method 2 扩展方法
var res = masterlist.SelectMany(m =>kongfulist,(m,k)=>new {master = m, kong =k}).Where(condition) //m=>kongfulist 将两个list联合,第二个参数(m,k)=>new {master = m, kong =k}表示返回两个对象
//join on 连接
var res = from m in masterlist
join k in kongfulist on m.kungfu equals k.name
where k.power > 90
select new{master = m,kongfo= k}
//group 分组查询
var res = from m in masterlist
join k in kongfulist on m.kungfu equals k.name
into groups
orderby groups.Count()
select new{kongfu = k,count = groups.Count()}
//group
var res = from m in masterlist
group m by m.kongfu into g
select new{count= g.Count(),Key = g.key} //g.Key()表示按照哪个属性分的组
特性
Obsolete用来提示旧方法
[Obsolete(“旧方法已经弃用,请使用新方法newMethod”)]
void oldMethod(){}
void newMethod(){}
[Obsolete(“旧方法已经弃用,请使用新方法newMethod”),true] //将旧方法表示为错误
Conditional将某个方法设置为不调用
[Conditional("isTest")] //表示必须定义“isTest”,才能正确调用test1函数。否则不调用,定义方法为宏定义: #define isTest
void test1(){}
void test2(){}
void test3(){}
调用者信息特性
调用者信息特性可以访问文件路径,代码行数,调用成员的名称等源代码信息
[CallerFilePath]:输出文件路径
[CallerLineNumber]:输出行数
[CallerMemberName]:输出成员名
void printOut(string str,[CallerFilePath] string fileName="",...)
DebuggerStepThrough特性,该特性修饰的函数在debug调试下,中断会跳过该函数
自定义特性
namespace 特性{
sealed class MytestAttribute:
}
程序集和命名空间
1.命名空间是同一类型的类的逻辑组合,不同命名空间需要using引用进来才可以使用
2.程序集是应用程序的部署单元,如dll/exe等,都是一个程序集,在解决方案里先建一个工程项目就是先建了一个程序集。
internal修饰的数据成员,可以在整个程序集中引用!