C#_基础
1、形参与实参
形参是函数定义时的参数,实参是函数被引用时传给它的参数
2、重载与重写
- 重载:发生在同一个类中,函数(方法)名相同但参数列表必须不同,返回类型可以不同
- 重写:发生在继承类之间,子类必须用override关键字来改写从父类继承过来的成员(函数、属性等),且函数的签名(函数名称、返回类型、参数列表)必须相同。父类中的函数在子类中只能被重写一次,被重写的函数必须有virtual或abstract或override修饰
3、virtual与abstract的区别
- virtual(虚拟的),abstract(抽象的) 两者都是指明被修饰的方法可以被派生类(子类)重写
- virtual修饰的方法必须有实现部分,abstract修饰的方法一定不能有实现
public virtual void Fun(){}
public abstract void Fun()
- virtual修饰的方法被子类重写,可有可无;abstract修饰的方法必须被子类重写
- abstract修饰的方法只能存在于抽象类中(用abstract修饰的类),virtual没这个限制
abstract public class Funs(){
public abstract void Fun();
}
4、接口
- 定义:是一种定义程序的协议(规范),用Interface声明,描述类或结构的一组行为。包含属性、索引器、时间和方法的任意组合,不能包含字段。
- 特点:作用:应用程序解耦;快速分离工作,提高开发效率;统一标准
- 继承接口的类必须实现接口的所有成员
- 接口不能直接实例化,可通过派生类来实例化
- 接口不能实现自己的成员,只能通过派生类来实现成员
- 例子:
public Interface IPerson
{
public string sex;
public void sleep();
.....
}
5、字段
- 是类或结构中的成员,字段使得类和结构可以封装数据。
- 字段通常为private,外部访问字段可通过方法、属性和索引器间接访问字段。
6、属性
- 属性可通过字段对数据进行简单的安全性检查,字段则不能
- 类或结构中的成员
- 属性中,get()是读取功能,set()是写入功能,两者决定属性是只读,只写还是读写
旧版C#写法: C# 6.0写法:
private string strname = "mike"; public string Name{ get; set; }="mike";
public string Name
{
get{return strname;}
set{strname = value;}
}
7、索引器
- 允许类和结构的实例按照与数组相同的方式进行索引,与属性类似,只是索引器(get/set)的访问权采用了参数
- this关键字是索引器的名称,value关键字定义由set分配的值
- 索引器可以被重载
- 索引器可以有多个形参,如访问二维数组
- 属性与索引器的作用与区别:
- 属性用于以可验证的方式访问私有成员变量。索引器用于以更便捷的方式访问对象中包含的成员数组或集合。
- 属性名可自定义,索引器必须以this命名。
- 属性可以为实例或静态,索引器必须是实例的。
- 索引器有索引参数列表,而属性没有
- 代码
class say<T>
{
private T[] arr = new T[10];//T是数据类型
public T this[int i]
{
get { return arr[i]; }
set { arr[i] = value; }
}
}
static void Main(string[] args)
{
say<string> s = new say<string>();
//string[] s = new string[5];
s[0] = "hello mike";
Console.WriteLine(s[0]);
Console.ReadKey();
}
8、结构与类
结构和类共享几乎所有相同的语法,区别在于:
- 结构struct关键字定义,类class关键字定义数据类型和行为。
- 结构是值类型,类是引用类型
- 结构没有析构函数,类有且只有一个析构函数
- 结构如果有构造函数,那么构造函数必须有参数
- 结构不能继承。所有结构的基类都是System.ValueType
- 结构的实例化不可用使用new运算符,除非其拥有构造函数
- 类是分配在内存的堆上,结构是分配在内存的栈上
9、构造函数
其名称与类名相同,用于实例化对象时,设置默认值,编写易阅读的代码
- 只要创建类或结构,就会调用它的构造函数。类和结构可以拥有多个不同参数的构造函数。
- 使用this关键字来调用同一对象中的另一个构造函数
- 使用base关键字调用其基类的构造函数
10、析构函数
与类同名,前面加~。作用:回收内存,隐士释放资源。
- 只存在类中,且一个类只有一个析构函数
- 析构函数无法继承和重载
- 不能手动调用,是自动调用。垃圾回收器决定何时调用,程序退出也会调用
- 析构函数没有修饰符,没有参数
- 建议不使用空的析构函数,避免性能丢失
11、委托
将一个方法作为另一个方法的参数进行传递,delegate关键字声明。这种将方法动态地赋给参数的做法,可以避免在程序中大量使用if-else(switch)语句,同时使得程序具有更好的可扩展性。
- 是一种引用方法的类型,可以理解为类。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。
- 委托方法的使用可以像其他任何方法一样,具有参数和返回值,与委托的签名(由返回类型和参数组成)匹配的任何方法都可以分配给该委托。
- 委托链:多个方法可以绑定在一个委托变量上,调用时被绑定的方法的执行顺序由绑定顺序决定
- 绑定方法:用 +=,移除方法:用-=
GreetingDelegate delegate1 = new GreetingDelegate();
delegate1 += EnglishGreeting; // 这次用的是 “+=”,绑定方法。
delegate1 += ChineseGreeting; // 给此委托变量再绑定一个方法
12、泛型
- 是一种数据类型,主要是将类型参数化,用T来定义,如Mylist<T>。
- 定义时不指明参数的具体数据类型,调用时必须指明。适用于类、方法、接口、委托
- 好处:提高代码的重用性,提高软件开发效率;编译时检查类型安全,减少装箱、拆箱,提高性能
13、 ==与equal的区别
- 对于字符串,两者比较的都是变量的值,效果一样。
- 对于非字符串的引用类型(非匿名类型),两者比较的都是变量的引用,不是其值。
- 对于匿名类型,equal比较的是变量的状态(其属性和值相同时,返回true),==比较的是变量的引用
14、static
- 修饰的对象是静态的。静态对象不能实例化
- 用途:当程序中所有实例共用的方法或者值,可以使用静态方法或静态字段。使用static时需注意线程安全,因为所有实例共用该静态对象,都可以更改他的值
- 静态类中只能有静态成员,不可以有非静态成员;
- 非静态类可以有非静态成员和静态成员,静态成员通过点的方式直接访问,非静态成员通过创建该类的实例访问;
- 静态类中的所有成员,无需创建实例就可以访问。访问方式:静态类名.成员
15、var与dynamic的区别
- var是动态推断类型,dynamic是动态类型。
- var变量的数据类型是在编译时决定的,编译时要进行类型检查,
- dynamic变量的数据类型是在运行时决定的,编译时不进行类型检查,在运行时进行类型检查。因此dynamic的效率比var低
- 实际上var与dynamic没有可比性
16、public、private、protect、Internal修饰符的访问权限
- public:公有成员,完全公开,无限制
- private:私有成员,该类的内部可以访问
- protect:保护成员,该类和继承类可以访问
- Internal:同一命名空间内可以访问
17、递归算法
- 自己调用自己。当调用次数太多时,效率很低。可用循环等其他方法代替
public int diguifun(int i)
{
int sum = 0;
if(i<0){ sum=0; }
else if(i==1){ sum=1; }
else{ sum = diguifun(i-1)+diguifun(i-2); }
return sum
}
18、冒泡排序算法
- 从小到大:两个for循环嵌套,两两相比较,交换位置(采用中间变量过度),小的放前面
19、