C# 学习记录
1:字段不能是虚拟的,只有方法、属性、事件和索引器才可以是虚拟的。当派生类重写某个虚拟成员时,即使该派生类的实例被当作基类的实例访问,也会调用该成员
2:C#允许把类和函数声明为abstract。抽象类不能实例化,而抽象函数不能直接实现,必须在非抽象的派生类中重写。显然,抽象函数本身也是虚拟的(尽管也不需要提供virtual关键字,实际上,如果提供了该关键字,就会产生一个语法错误)。如果类包含抽象函数,则该类也是抽象的,也必须声明为抽象的。
3:C#允许把类和方法声明为seaIed。对于类,这表示不能继承该类;对于方法,这表示不能重写该方法
4:B:A,C:B,在实例化一个C时,会运行C的构造函数,接着C的构造函数运行B的构造函数,接着B的构造函数运行A的构造函数,接着A的构造函数运行System.Object的构造函数,System.Object没有直接基类,其构造函数就会被执行,之后把控制权交给A的构造函数并执行[初始化其字段],之后把控制权交给B的构造函数并执行[初始化其字段],之后把控制权交给C的构造函数并执行[初始化其字段],自此C的实例化工作完成。
注意:在整个过程中,每个类都初始化自己类中的字段
5:构造函数后面有有三种情况
public A(string paraA,string paraB):this(paraA) public A(string paraA,string paraB):base(paraA) public A(string paraA,string paraB)
{} {} {}
1):第一种是类本身构造函数之间的相互调用,第二种是显示指定派生类调用父类的带一个参数的构造函数
2):如果没有指定如第三中情况,则默认是会调用类A直接基类的无参构造函数(当然如果父类没有提供该构造函数,编译器会报错)
6:不能把类型定义为protectcd、private和protected internal,因为这些修饰符对于包含在名称空间中的类型没有意义。因此这些修饰符只能应用于成员。但是,可以用这些修饰符定义嵌套的类型(即包含在其他类型中的类型,因为在这种情况下,类型也具有成员的状态)
如果有嵌套的类型,则内部的类型总是可以访问外部类型的所有成员。甚至可以访问外部类型的私有成员
7:在.net中,协变和抗变是指对方法的参数和返回值类型进行转换,参数类型是协变的,方法的返回类型是抗变的
8:Array的Copy与Clone方法的区别,Clone会创建一个新的数组,而Copy()要求传递阶数相同且有足够元素的已有数组
Array intArray = Array.CreateInstance(typeof(int), 2);
intArray.SetValue(2, 0);
intArray.SetValue(3, 1);
int[] int1 = (int[])intArray;
int[] int2 = (int[])int1.Clone();
int[] int3 = new int[2];
int1.CopyTo(int3, 0);
9:IComparer接口与IComparable接口的区别
1):IComparable接口是在需要比较的类中实现的
2):IComparer接口比较灵活,它是其他类实现,假如不能修改在数组中用作元素的类,也就是说被比较的类本身的代码不能修改,就可以定义一个类实现此接口即可
例子:
#region IComparable方式
/// <summary>
/// 在Person类中实现IComparable
/// </summary>
public class Person : IComparable<Person>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int CompareTo(Person other)
{
if (other == null)
throw new ArgumentNullException("other");
int result = this.FirstName.CompareTo(other.FirstName);
if (result == 0)
result = this.LastName.CompareTo(other.LastName);
return result;
}
}
#endregion
#region IComparer方式
/// <summary>
/// 重新定义比较类PersonCompare
/// </summary>
public class PersonCompare : IComparer<Person>
{
private PersonCompareType _compareType;
public PersonCompare(PersonCompareType compareType)
{
_compareType = compareType;
}
public int Compare(Person x, Person y)
{
if (x == null)
throw new ArgumentNullException("x");
if (y == null)
throw new ArgumentNullException("y");
switch (_compareType)
{
case PersonCompareType.FirstName:
return x.FirstName.CompareTo(y.FirstName);
case PersonCompareType.LastName:
return x.LastName.CompareTo(y.LastName);
default:
throw new ArgumentException("compare type");
}
}
}
/// <summary>
/// 比较方式
/// </summary>
public enum PersonCompareType
{
FirstName,
LastName
}
#endregion
Person[] persons ={
new Person{FirstName="Zheng",LastName="Li"},
new Person{FirstName="Bao",LastName="Shen"},
new Person{FirstName="Yi",LastName="Liu"}
};
//Person实现了IComparable
Array.Sort(persons);
//定义新类PersonCompareIComparer,并实现IComparer
Array.Sort(persons, new PersonCompare(PersonCompareType.FirstName));
Console.ReadLine();
10:接口的实现分为显示和隐式
1)显示实现时接口成员必须显示指定接口的名称,此时对象无法直接访问该接口成员,必须强制转换为接口,然后通过接口访问该成员
2)隐式实现时,既可以通过接口访问,也可以通过对象本身访问
3)之所以又显示实现这一说,是因为在类实现多个接口时,多个接口可能包含签名相同的接口成员,这时必须采用显示声明的方式来实现指定接口的成员