Office中国论坛/Access中国论坛
标题: 【读书】图解教程-西西 [打印本页]
作者: pengjia89 时间: 2014-3-21 02:27
标题: 【读书】图解教程-西西
本帖最后由 pengjia89 于 2014-3-24 21:34 编辑
第一章
C#中的主要需要记住的基础概念
CLR公共语言运行库
CIL中间语言,所有的代码都会编译成中间语言。
CLI公共语言基础结构
C#的优点
C#有自动垃圾回收机制
作者: luozh7682 时间: 2014-3-21 14:56
这些概念虽然简单,可是不好理解透彻。
作者: 好运牛 时间: 2014-3-21 19:06
谢谢美女老师西西
作者: pengjia89 时间: 2014-3-24 21:32
本帖最后由 pengjia89 于 2014-3-24 21:33 编辑
第二章
这章主要是一个对于C#程序的概括解释
和C/C++不同,不是用include声明引用的头文件,而是通过using的方式,声明引用的命名空间。
命名和C/C++类似,并且也是区分大小写的,这件事情在VBA里面,曾经让我无敌地郁闷。
Console.Write和Console.WriteLine最大的区别就是后者会在后面加一个回车哦。
C#中,用{0}的格式,输出格式化字符串哦。
注意和C/C++中一样,//和/**/的格式
///的格式的注释,是文档注释,包含XML文本,可以使用工具生成程序文档。
作者: pengjia89 时间: 2014-3-24 21:32
第三章
1、C#的中的数值不具有bool特性。
2、dynamic在使用动态语言编写的程序集时使用,这个不太明白,看到后面需要补充!!
动态化的静态类型
3、对于引用类型,引用是存放在栈中,而数据是存放在堆里
如图所示的内容,需要记住一下
[attach]53652[/attach]
4、引用类型的变量值可以为null,而值类型的变量不可
5、创建可空类型
可以从任何值类型创建可空类型,包括预定义的简单类型
不可以从引用类型或其他可空类型创建可空类型。
不需要在代码中空类型,只需要声明可空类型的变量即可。编译器会自动隐匿创建可空类型。
int?myInt1 = 15;// 将int隐式转换为int?
intregInt = (int)myInt;//将int?显式转换为int
作者: pengjia89 时间: 2014-3-24 21:35
第十五章
委托是C#的一个很重要的知识点。
1、什么是委托
委托在我认为,就是一系列格式相同的方法列表,可能就是定义的名称不一致,参数、返回值等都是一样的。
2、如何声明委托
delegate
void MyFunc( int x );
delegate是声明委托的关键字,void是返回值,int x是函数的参数,MyFunc是委托的类型名。
3、创建委托对象
<p class="MsoNormal"><span lang="EN-US" style="font-family:"微软雅黑","sans-serif"">MyFunc
funcTest;//</span><span style="font-family:"微软雅黑","sans-serif"">声明委托<span lang="EN-US"><o:p></o:p></span></span></p>
4、创建委托的标准形式
funcTest
= new MyFunc(Test);
5、创建委托的简写
funcTest
= Test;
6、委托方法的赋值
①直接赋值
<p class="MsoNormal"><span lang="EN-US" style="font-family:"微软雅黑","sans-serif"">funcTest
= Test1;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:"微软雅黑","sans-serif"">funcTest
= Test2;<o:p></o:p></span></p>
如果是直接赋值的委托,重新赋值之后,将无法调用之前所赋的值。
②组合委托
<p class="MsoNormal"><span lang="EN-US" style="font-family:" 微软雅黑","sans-serif""="">MyFunc
<p class="MsoNormal"><span lang="EN-US" style="font-family:"微软雅黑","sans-serif"">MyFunc
funcTest1 = Test1;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:"微软雅黑","sans-serif"">MyFunc
funcTest2 = Test2;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:"微软雅黑","sans-serif"">MyFunc
funcTest3 = funcTest1 + funcTest2;<o:p></o:p></span></p>
但是,如果是组合委托即加法形式,则是增加委托列表的函数。
③增加委托方法
funcTest
+= Test2;
④删除委托方法
funcTest
-= Test1;
7、委托会依次调用队列里面的方法,然后最后输出结果哦
8、委托的方法有三种方式
<p class="MsoNormal"><span lang="EN-US" style="font-family:"微软雅黑","sans-serif"">class
TestDel<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:"微软雅黑","sans-serif"">{<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent:6.0pt"><span lang="EN-US" style="font-family:
"微软雅黑","sans-serif"">static void func1( int a);<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent:6.0pt"><span lang="EN-US" style="font-family:
"微软雅黑","sans-serif"">void func2(int b);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:"微软雅黑","sans-serif"">}<o:p></o:p></span></p>
①静态方法
funcTest
= TestDel.func1;
②实例化的方法
<p class="MsoNormal"><span lang="EN-US" style="font-family:"微软雅黑","sans-serif"">TestDel
cTest = new TestDel();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:"微软雅黑","sans-serif"">funcTest
= cTest.func2;<o:p></o:p></span></p>
③匿名方法
<span lang="EN-US" style="line-height: 1.5; font-family: 微软雅黑, sans-serif;">funcTest
= delegate( int x ){//</span><span style="line-height: 1.5; font-family: 微软雅黑, sans-serif;">实现代码<span lang="EN-US">};</span></span>
9、Lambda表达式
Lambda表达式的简洁,像最简写的的Lambda表达式,可以把
funcTest
= delegate( int x){return x+1;};
简写为
funcTest
= x => x+1;
说真的,刚开始一直知道有Lambda和Linq这两样东西,但是一直都下不下决心去看,这次也正好趁这个机会,好好地看一下。
虽然只是列了一下大概的知识点,但是,也算是看完了,哇哈哈
作者: faunus 时间: 2014-3-24 23:34
编译期先看成 object,
运行期看成强制类型。
但本质上还算静态类型。
作者: pengjia89 时间: 2014-3-31 00:17
第四章
类成员包括数据成员和函数成员。
和C/C++不同,C#在类型的外部不能声明全局变量,所有的字段都属于类型,而且必须在类型声明内部声明。
和C/C++不同,方法没有返回默认类型,所有方法必须包含返回类型或 void。
有5种成员访问控制
1、private
2、public
3、protected
4、internal
5、protected internal
如果不声明,则是隐式声明私有
作者: pengjia89 时间: 2014-4-1 11:56
C#图解教程读书笔记(第5章 方法)
类型推断和var关键字
从C#3.0开始,可以在变量声明的开始部分的的位置使用新的关键字var。
Var关键字并不是某种特别类型的符号。它只是句法上的速记,表示任何可以从初始化的右边推断出的类型。
Var的一些重要条件:1、只能用于本地变量,不能用于字段2、只能在变量声明中包含初始化时使用3、一旦编译器推断出变量的类型,它就是固定且不能更改的。在C/C++中,可以先声明一个本地变量,然后在嵌套块中声明另一个相同名称的本地变量。在内部范围,内部名称掩盖了外部名称。然而,在C#中,不管嵌套级别如何,都不能在第一个名称的有效范围内声明另一个同名的本地变量。
参数的几种类型1、值参数在栈中为形参分配空间,复制实参到形参
[attach]53699[/attach]
2、引用参数使用引用参数时,必须在方法的声音和调用中都使用ref修饰符。
参数必需是变量,在用作实参前必需被赋值,如果是引用类型变量,可以赋值为一个引用或null值。
void MyMethod(ref int val){}//方法声明
int y = 1;//实参变量
MyMethod(ref y);//方法调用
对于引用参数,形参的参数名看起来就好像是实参变量的别名,也就是说,它们指向的是相同的内存位置。
[attach]53700[/attach]
3、输出参数如同引用参数,输入参数有以下要求
必需在声明和调用中都使用修饰符,输出参数的修饰符是out。
和引用参数相似,实参必需是变量,而不能是其它类型的表达式。
void MyMethod(out int val){}//方法声明
int y=1;
MyMethod(out y);//方法调用
输出参数不能在赋值之前读取。这意味着参数的初始值是无关的,而且没有必要在前为实参赋值。
在方法返回之前,方法内部的任何贯穿的可能路径都必须为所有输出参数进行一次赋值。
[attach]53701[/attach]
4、参数数组在一个参数列表中只能有一个参数数组。
如果有,它必须是列表中的最后一个。
使用params修饰符。
在数据类型后放置一组空的方括号。
void ListInts(params int[] iVals){}
求平均数的示例
static intIntAverage(params int[]iIn)
{
int iAvg = 0;
if ((iIn != null)&& (iIn.Length != 0))
{
for(int i = 0; i < iIn.Length; i++ )
{
iAvg += iIn;
}
}
iAvg = iAvg / iIn.Length;
return iAvg;
}
int[] iTemp = newint[] { 1, 2, 3, 4 ,-1,-3,100};
Console.WriteLine("平均数是{0}",IntAverage(1,2,3,4,5,6,7));
Console.WriteLine("平均数是{0}", IntAverage(iTemp));
[attach]53702[/attach]
5、数组作实参参照上面的使用方法。
方法重载:一个类中可以有一个以上的方法拥有相同的名称,这叫做方法重载。
long AddValue(longa, long b) { returna + b; }
int AddValue(longa, long b, longc) { return (int)(a+ b + c); }
命名参数:重要:从C#4.0开始,只要显式指定参数的名称,就可以以任何顺序在方法调用中列出实参。
public longAddValue(long a, longb)
{
Console.WriteLine("a是o?{0},b是o?{1}", a, b);
return a + b;
}
FuncTest cFuncTest = new FuncTest();
cFuncTest.AddValue(b: 5, a: 4);
输出为:[attach]53703[/attach]
之前VBA一直是可以只设定固定某个参数的值,而其它不管的,这样的话,C#也可以是那样的调用方式了。
可选参数:省略必需从最后开始
public int AddValue(long a, long b=3, long c=4) { return (int)(a + b + c); }
调用时可以:
Console.WriteLine("和是{0}", cFuncTest.AddValue(5, c: 10));
返回是18哦
栈帧在调用方法的时候,内存从栈的顶部开始分配,保存和方法关联的一些数据项,这块内存叫方法的栈帧(stack frame)。
栈帧包含的内容保存如下内容:返回地址,也就是在方法退出的时候,继续执行的位置。
这些参数分配的内存,也就是方法的值参数,或者还可能是参数数组(如果有的话)。
各种和其他管理数据项。
在方法调用时,整个栈帧都会压入栈。在方法退出时,整个栈帧都会从栈上弹出,弹出栈帧有的时候也叫做栈展开(unwind)。
递归除了调用其他方法,可以调用自身,这叫做递归。
作者: pengjia89 时间: 2014-4-1 11:57
C#图解教程读书笔记(第6章 类进阶)
类成员声明语句由下列部分组成:核心声明、一组可选的修饰符和一组可选的特性(attribute)。
[特性] [修饰符] 核心声明
修饰符:如果有修饰符,必须放在核心声明之前。
如果有多个修饰符,要有序放置
特性如果有特性,必须放在修饰符和核心声明之前
如果有多个特性,可以任何顺序
修饰符:public,private,static,const
实例类成员public int Mem1;
静态字段static int Mem2;被所有的实例可见,并且如果一个实例改变该值,其它实例使用的该值也会变化。
[attach]53704[/attach][attach]53704[/attach]
静态成员可以不用实例化,直接使用。
静态函数成员Static public void PrintValA();
成员常量Const int IntVal = 100;// 定义int类型常量,值为100
属性属性是代表类的实例或类中的一个数据项的成员。
private inttheRealValue;
public intTheRealValue
{
get{ return theRealValue; }
set{ theRealValue = value; }
}
但是使用属性的话,不能直接用get和set,而是直接使用赋值的方式。
构造函数如果需要外部调用,需要声明为public
和类名相同,但是没有返回类型。
析构函数每个类只能有一个析构函数
析构函数不能带参数
析构函数不能带访问修饰符
析构函数和类有相同的名称,但以一个“~”字符作前缀
析构函数只对类的实例起作用,因为没有静态析构函数。
不能在代码中显式地调用析构函数。
标准的清理模式 class FuncTest:IDisposable
{
bool disposed = false;
public voidDispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~FuncTest()
{
Dispose(false);
}
protected virtualvoid Dispose(booldisposing)
{
if(disposed == false)
{
if(disposing == true)
{
//Dispose the managed resources
}
//Dispose the unmanaged resources
}
disposed = true;
}
}
readonly修饰符和const不同,即可以直接初始化,也可以在构造函数中设置它的值。
但是,如果是static字段,初始化必需在static构造函数中完成。
this关键字this关键字在类中使用,是对当前实例的引用。
索引和属性一样,索引不分配内存为存储
索引和属性都主要被用来访问其它数据成员这些成员和它们关联,它们为这些成员提供设置和获取访问。
和属性一样,索引可以只有一个访问器,也可以两个都有。
索引总是实例成员,因此,索引不能声明为static。
和属性一样,实现get和set访问器的代码不必一定要关联到某个字段或属性。这段代码可以做任何事情或什么也不做,只要get访问器返回某个指定类型的值即可。
class Employee
{
public stringLastName;
public stringFirstname;
public stringCityOfBirth;
public stringthis[int index]
{
set
{
switch(index)
{
case0: LastName = value;
break;
case1: Firstname = value;
break;
case2: CityOfBirth = value;
break;
default:
throw new ArgumentOutOfRangeException("index");
}
}
get
{
switch(index)
{
case0: return LastName;
case1: return Firstname;
case2: return CityOfBirth;
default:
throw new ArgumentOutOfRangeException("index");
}
}
}
}
当一个类中,有多个string和多个int想同时定义索引时,可以将索引定义为多个参数。
分部类和分部类型用partial class的形式,声明分部类
partial classMyClass
{
partial voidPrintSum(int x, inty);
public voidAdd(int x, inty)
{
PrintSum(x, y);
}
}
partial classMyClass
{
partial voidPrintSum(int x, inty)
{
Console.WriteLine("Sum is {0}", x + y);
}
}
varmc = new MyClass();
mc.Add(5, 6);
作者: pengjia89 时间: 2014-4-3 19:47
C#图解教程读书笔记(第7章 类和继承)
1、所有的类都继承自object2、如何隐藏基类的成员要隐藏一个继承的数据成员,需要声明一个新的相同类型的成员,并使用相同的名称。
通过在派生类中声明新的带有相同签名的函数成员,可以隐藏或掩盖继承的函数成员。请记住,签名由名称和参数列表组成,但不包括返回类型。
要让编译器知道你在故意隐藏继承的成员,使用new修饰符,没有它,程序可以成功编译,但编译器会警告你隐藏了一个继承成员。
也可以隐藏静态成员。
class SomeBase
{
public string cFiled;
}
class SomeClass: SomeBase
{
new public string cFiled;
}
3、基类访问使用base.的形式。4、虚方法和覆写方法基类的方法使用virtual,派生类的方法使用override,这样,就可以在派生类中,改变基类的方法。
覆写的方法和被覆写的方法必须有相贩可访问性,换一种说法,被覆写的方法不能是private,而覆写的方法是public。
不能覆写static或非虚方法。
方法、属性和索引,以及称为事件的另一种类型,它们都可以被声明为virtual和override。
用override和new覆写函数
class Program
{
static void Main(string[]args)
{
MyBaseClasscBase = new MyBaseClass();
cBase.Print();
MyDerivedClasscDevrived = new MyDerivedClass();
cDevrived.Print();
SecondDerivedcSecond = new SecondDerived();
cSecond.Print();
MyBaseClasscBase2 = (MyBaseClass)cSecond;
cBase2.Print();
cBase2.Print2();
Console.ReadKey();
}
}
class MyBaseClass
{
virtualpublic voidPrint()
{
Console.WriteLine("This is the base class");
}
virtualpublic voidPrint2()
{
Console.WriteLine("This is the base class");
}
}
class MyDerivedClass: MyBaseClass
{
public override void Print()
{
Console.WriteLine("This is the derived class");
}
overridepublic voidPrint2()
{
Console.WriteLine("This is the derived class");
}
}
class SecondDerived: MyDerivedClass
{
public override void Print()
{
Console.WriteLine("This is the Second Derived Class");
}
new public void Print2()
{
Console.WriteLine("This is the Second Derived Class");
}
}
输出内容:
[attach]53711[/attach]
用override不仅可以覆写函数,还可以覆写属性。
5、构造函数的顺序[attach]53712[/attach]
6、声明为public的程序,可以跨程序集继承。7、访问成员的区域private只在类的内部可访问
internal对该程序集内所有类可访问
protected对所有继承该类的类可访问
protectedinternal 对所有继承该类或在该程序集内声明的类可访问
public对任何类可访问
8、抽象成员用abstract修饰符标记,方法、属性、事件、索引均可以抽象。抽象成员没有实现体,被分号取代。而且必须被覆写。
①尽管抽象成员必须在派生类中用相应的成员覆写,但不能把virtual修饰符加到abstract修饰符。
②就像虚成员,派生类中抽象成员的实现必须指定override修饰符。
9、抽象类抽象类只能用作其它类的基类不能实例化。用abstract声明。
任何派生自抽象类必须使用override关键字实在该类所有的抽象成员,除非派生类自己也是抽象类。
10、密封类用sealed声明,必须是独立的类,不能用作基类。
11、静态类静态类需要声明为static,所有成员必需是静态的,可以有静态构造函数,但没有实例构造函数,不能创建该类的实例。静态类是隐匿是密封的。
12、扩展方法 class MyData
{
privatedouble dbD1;
privatedouble dbD2;
privatedouble dbD3;
publicMyData(double d1, doubled2, double d3)
{
dbD1 = d1;
dbD2 = d2;
dbD3 = d3;
}
public double Sum()
{
returndbD1 + dbD2 + dbD3;
}
}
static classExtendMyData
{
public static doubleAverage(this MyDatamd)
{
returnmd.Sum() / 3;
}
}
则可以直接用以下方法调用:
MyDatamd = new MyData(3,4, 5);
Console.WriteLine("Average:{0}", md.Average());
Console.ReadKey();
this必需作为第一参数,如果需要给 Average加参数,参考如下:
publicstatic doubleAverage(this MyDatamd,int icount)
{
returnmd.Sum() / icount;
}
调用时:
MyDatamd = new MyData(3,4, 5);
Console.WriteLine("Average:{0}", md.Average(3));
Console.ReadKey();
作者: pengjia89 时间: 2014-4-14 12:16
C#图解教程读书笔记(第8章 表达式和运算符)
表达式字面量整数字面量[attach]53808[/attach]
字符字面量[attach]53809[/attach]
字符串字面量
求值顺序优先级[attach]53810[/attach]
结合性[attach]53811[/attach]
与C和C++不同,在C#中的数字不具有布尔意义。
各种运算符的作用(过)
用户定义类型转换class XiXiInt
{
const intiMaxValue = 100;
const intiMinValue = 0;
private inttheValue = 0;
public intTheValue
{
get{ return theValue; }
set
{
if(value < iMinValue)
{
theValue = iMinValue;
}
else
{
theValue = value > iMaxValue ? iMaxValue : value;
}
}
}
public staticimplicit operatorint(XiXiIntiXiXi)
{
returniXiXi.TheValue;
}
public staticimplicit operatorXiXiInt(intx)
{
XiXiIntiXiXi = new XiXiInt();
iXiXi.TheValue = x;
returniXiXi;
}
}
显式转换和强制转换运算符如果将implicit改为explicit的话,则需要显式强制转换。
运算符重载运算符重载只能用于类和结构。
作者: pengjia89 时间: 2014-4-14 18:34
第9章
文件头的Using是Using指令,不是using语句
using (TextWriter tw = File.CreateText("xixi.txt"))
{
tw.WriteLine("XiXi");
}
欢迎光临 Office中国论坛/Access中国论坛 (http://www.office-cn.net/) |
Powered by Discuz! X3.3 |