目录
1.1 官方编程文档
1.2 类与结构
1.3 引用类型与值类型
1.4 ref参数与out参数
1.5 方法重载
1.6 静态类与静态成员
1.7 继承与多态
1.9 抽象类与接口
1.10 拓展方法
1.11 委托与事件
1.12 枚举类型
1.13 数组
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC#\Specifications\2052\CSharp Language Specification.doc
属性 | 描述对象的特征,也可对字段进行封装(get,set) |
字段 | 类或结构体内部定义的变量 |
方法 | 类的某种动作或行为 |
构造器 | 构造函数,在创建实例对象时调用,来进行类的初始化工作 |
事件 | 特定条件下触发的行为 |
结构只能定义带参构造函数,不能继承和派生,但可以实现接口
结构中不能实例字段初始值
类是引用类型
class Program
{
static void Main(string[] args)
{
person p1 = new person();
person p2 = p1;
p1.Name = "Jack";
p1.Age = 30;
Console.WriteLine(p2.Name + p2.Age.ToString());
p1.Name = "Bob";
p1.Age = 27;
Console.WriteLine(p2.Name + p2.Age.ToString());
}
}
class person
{
public string Name { set; get;}
public int Age { set; get; }
}
结构是值类型
class Program
{
static void Main(string[] args)
{
person p1 = new person();
person p2 = p1;
p1.Name = "Jack";
p1.Age = 30;
Console.WriteLine(p2.Name + p2.Age.ToString());
p1.Name = "Bob";
p1.Age = 27;
Console.WriteLine(p2.Name + p2.Age.ToString());
}
}
struct person
{
public string Name { set; get;}
public int Age { set; get; }
}
引用对象与值对象的总结
static void getPerson1(person p)
{
p.Name = "Amiee";
p.Age = 25;
}
//此版本对参数p的操作会反应到实参中
static void getPerson2(person p)
{
p = new person("Ray", 27);
}
//此版本在传参数时,参数p指向的实参对象,但是进入函数后,参数p的指向发生了变化,对p参数的操作便不会再反映到实参中
上述两个函数的阐述传递过程如下:
为解决上述问题,引入ref参数和out参数:
ref参数传入前必须初始化,out传入前不用初始化
static void getPerson3(ref person p)
{
p = new person("Ray", 28);
}
static void getPerson4(out person p)
{
p = new person("Ray", 29);
}
均完成了对实参的修改
具有不同返回值的同名方法可重载
具有不同参数个数、参数类型和参数顺序的同名方法
有无ref或out修饰符修饰的同名方法
静态类的所有成员都必须的是静态的
类的静态成员可用类名直接调用
(1)可访问性
对internal可访问性的验证见博文https://blog.csdn.net/m1m2m3mmm/article/details/95667772
(2)继承
(3)覆盖与多态
(4)定义不可被继承的类
sealed class ClassName
{
};
抽象类可以定义非抽象成员,这些成员被其派生类继承;抽象类的不能被实例化
非抽象类不能定义抽象成员
接口与抽象类的区别:【参考之前博文类与对象学习小结】
接口的显式实现
在实际的开发过程中,如果多个接口定义命名的成员,而这些接口又同时被同一个类实现,此时为了避免成员之间的冲突,需提供对接口的显式实现,在方法调用时,只能通过定义接口进行调用;通过实现类对象无法进行调用,除非将其强制转化为对应的接口。
在不继承的前提下,对现有类型进行拓展;拓展方法定义在静态类中的静态方法
//拓展方法的定义
public static class stringExt//静态类,静态成员
{
//将字符串转化为空格分开的字符串
public static string SplitSpace(this string str)
{
return string.Join(" ", str.ToCharArray());
}
//将数值转化为其绝对值
public static int abs(this int num)
{
return num >= 0 ? num : 0 - num;
}
}
调用拓展方法
string str = "Ray";
Console.WriteLine(str.SplitSpace()); //并不会对str的值产生任何影响,只是产生了一个新的空格分割字符串
int num = -10;
Console.WriteLine(num.abs().ToString());
事件是委托类型,要声明事件就需要定义事件封装类型的委托;然后在类中使用event关键字,同时为了让派生类可以重写该事件,常将其定义为protected类型。习惯上,事件的命名方式为On<事件名>
以学生听到铃声就知道是下课为例,说明事件与委托的关系:铃声响,代表事件发生;学生知道下课就是对事件的响应
标准事件与委托
更为详细的分析见博文委托与事件
使用枚举类型的好处:
避免意外的调用,调用者只能在给定的值当中做出选择;
可读性强,调用可以方便的识别各枚举值代表的含义
枚举类型继承自Enum类,该类是ValueType类型的派生类,可知枚举类型属于值类型
enum week
{
mondey,friday,sonday
}
枚举类型的基础类型为int,默认从0开始,后值在前值基础上+1
var myWeek = Enum.GetValues(typeof(week));//获取枚举类型中的所有值到一个对应类型的数组中
string name = Enum.GetName(typeof(week), 2);//sonday
string names = Enum.GetNames(typeof(week));//所有项
声明与赋值
//先声明后赋值
type[] arr = new type[count];
arr[0] = value1;
arr[1] = value2;
//声明同时赋值
type[] arr = new type[] {valueList};
type[] arr = {valueType};
//二维数组
type[,] arr = new type[rowCount, colCount];
arr[0,0] = value00;
arr[0,1] = value01;
数组遍历
for(int i = 0; i < arr.Count; i++)
{
Console.Writeline(arr[i].ToString());
}
//所有数组继承自IEnumerable,可以使用foreach遍历
foreach(type var in arr)
{
Console.Writeline(var.ToString());
}
方法 | 描述 | 返回值 |
Array.Reverse(arr); | 字符串反转 | T[] |
Array.Resize |
改变数组大小;哈希值会发生变化 | T |
Array.Find(arr, new Predicate |
从头查找满足某规则的值 | T |
Array.Findlast(arr, new Predicate |
从尾部查找满足某规则的值 | T |
Array.FindAll(arr, new Predicate |
查找所有满足某规则的值 | T[] |
上述第二组方法需要用到Predicate委托,原型如下:
T为参数类型,obj为数组中待查找元素应满足条件的方法名
private static bool findProc(T obj)
{
if(条件一)
{
//处理代码1
return ture;
}
if(条件二)
{
//处理代码2
return false;
}
}