【简述】:本章主要讲述类相关的字段、属性、方法。其中字段与属性介绍了初始化方式、WPF依赖属性等,方法介绍了运算符重载、分部方法、扩展方法以及与方法相关的命名参数、可选参数、方法的JIT编译原理等。
第一节 、字段与属性的初始化方式汇总
1、对象与集合初始化器:可初始化部分的字段。
A obj3 = new A{IntValue = 100}; //对象初始化器
List<A> objs = new List<A>{ //集合初始化器
new A{IntValue =100},
new A{IntValue =200}
};
【注意】使用初始化器时,类A必须要定义无参数的构造函数,而且属性IntValue是Public,否则编译不能通过。
2、 自动实现的属性
A、 class A
{ public int IntValue {get;set;} }
B、 当定义只读的属性时
class MyClass
{ public ReadOnlyValue {get;private set;}
3、 声明式的属性初始化方式:
<asp:Button ID=”Button
4、 基于反射初始化对象字段与属性
public class MyHost{
[Import(typeof(IplugIn))]
Public IplugIn plugin = null;
//……
}
第二节、让一个方法返回多个结果
1、 在方法体外定义变量保存结果,即利用公有字段保存其值。
2、 使用“输出型”和“引用型”参数。
void Divide(int x,int y,out int quotient); //quotient为输出型参数
Divide(10,3,out quotient) //调用时在实参前要加out关键字。
void Divide(int x,int y,ref int quotient); //quotient为引用型参数
Divide(10,3,ref quotient) //调用时在实参前要加ref关键字。
3、 让方法返回一个对象或结构变量。
4、 使用Tuple 对象作为方法的形参或返回值
A、 Tuple类代表一个有序的N元组,比如3元组(100,200,300)
B、 使用new 关键字直接创建一个Tuple对象,它支持1~7个泛型参数的泛型Tuple.
static Tuple<int,int> Divide(int x,int y)
{ return new Tuple<int,int>(x / y,x % y); }
调用: Tuple<int,int> result = Divide(10,3);
Console.WriteLine(“{0} {1}”,result.Item1,result.Item2);
C、 Tuple实现了IStructuralEquatable、IstructuralComparable、Icomparable接口
D、 Tuple的元素可指定为任意类型,这使得它有很强的表达力的数据类型。
第三节 命名参数与可选参数
1、 意义:A、为方便快捷地调用本地COM组件中的方法。B、可以减少重载方法的数量。
2、 命名参数的例子: static void SomeMethod(int x1,int x2,int y1,int y2)
调用时:SomeMethod(x1:100,y1:300,x2:200,y2:400); //命名方式,次序无关紧要
3、可选参数:是指给方法的特定参数指定默认值,在调用方法时,可以省略掉这些参数。
static void Test(int required,string optionalString=”Default Value”) {……}
Test(100); //optionalString参数拥有默认值”Default Value”
Test(100,”New Value”); //optionalString参数的值为”New Value”
4、拥有可选参数的重载方法的调用原则:
A、根据实参类型,参数最接近的方法被调用。
B、如果根据上条规则有两个或多个重载方法都可以被调用,选择参数个数最小的。
第四节 运算符重载
1、 运算符重载:本质是一种特殊的方法而矣,使得外界调用更直观、更简单。
2、 重载运算符的方法,一定是静态的,重载的方法参数通常是一个或两个。
3、 例子: public static int[] operator + (MyIntArray x ,MyIntArray y)
调用时: MyIntArray x= new MyIntArray();MyIntArray y= new MyIntArray();
int[] sum = x + y; //调用重载的加法运算符
第五节 分部类与分部方法
1、分部类:
A、分部类:定义一个类时加上partial 关键字,此类即成为分部类,分部类允许将一个的代码分散于一个以上的源文件中。它是 C#编译器特性,而非CLR的。
B使用分部类的原则:A、所有需要“合并”的类必须都用partial关键字声明;B、所有的需要“合并”的类必须位于同一项目中。
C意义:用于隔离来源不同、功能不同或类型不同的源代码。
D应用实例:Silverlight、WPF、asp.net项目中。
2、分部方法:
A、定义:将方法声明与方法实现代码分布于不同的文件中,使用partial关键字定义。
B、特性:分部方法不能是公有的。它允许只有声明,没有方法实现。
C、功用:功能扩展。即我们可以向某个方法“动态注入”附加的功能代码
D、案例:在LINQ to SQL中,使用分部方法为将数据实体对象保存到数据库添加自定义的业务逻辑。
第六节 奇特的扩展方法
1、 意义:它使得我们能向现有的数据类型“动态”添加办法,而不需要创建新的派生类型、重新编译或直接修改原始类型的源代码。扩展方法已在.net中广泛地使用。
2、 扩展方法必须是静态的,并且需要放在一个非泛型的静态类中。扩展方法的第一个参数前必须有一个this关键字,它指明此扩展方法将附加于哪个类型的对象上。
3、 本质:扩展方法纯粹是“语法糖”,从IL中可看出这些扩展方法转换为相应静态方法的调用,与被扩展的类型其实一点关系也没有!
4、 案例:Enumerable与IEnumerable接口的关系?
答:Enumerable是一个静态类,而IEnumerable是一个接口,它们之间不是继承关系,而是扩展关系----即扩展了IEnumerable 的方法,并提供了一组用于查询实现此接口的对象的静态方法。比如
List<int> list = new List<int>();
list.Sum(); //List类实现了IEnumerable接口
5、 因为扩展方法很好地体现了修改封闭、扩展开放的面向对象设计原则,所以建议广泛地运用此特性。
第7章 剖析WPF依赖属性
1、 意义:它是WPF技术的基础,比如数据绑定、样式、动画等,都必须应用于依赖属性之上。
2、 性质:
A 依赖属性使用一个独特的字段来保存数据,此字段的类型为DependencyProperty.
B 依赖属性所在的类继承自DependencyOject。
C 有些依赖属性可以被子元素继承。
D 包含自己的数据验证机制。
E 设置其默认值。
F 监视其他属性的改变,并依据具体情况“主动”修正自己的值。
3、自定义依赖属性的步骤:
A、让类派生自DependencyObject。Public class Test:DependencyObject{……}
B、定义一个用于保存依赖属性值的字段
Public static readonly DependencyObject MyPropertyProperty =
DependencyObject.Register{
“MyProperty”, //依赖属性名
“typeof(int), //依赖属性所保存数据的类型
“typeof(Test),//依赖属性所属的类
New PropertyMetadata() //用于描述依赖属性特性的元数据。
}
C、添加一个”CLR”包装器
Public int MyProperty
{
get { return (int)GetValue(MyPropertyProperty);}
set { SetValue (MyPropertyProperty,value); }
}
感想:C#的新特性实在太多了,我在想这样发展下去,会不会真得像C++十分复杂呢?