C#和.NET 2.0实战
平台、语言与框架
[法]Patrick Smacchia著
施凡 李永伦 谭颖华 徐宁 译
2008年1月第1版
1.3.3Mono项目
使用MonoDevelop 2.8.2
foreach循环语句是C#中特有的。
static void Main(string[] args)
{
int[] HTankindexArr1 = {0,11,10,9,8,7,6,5,4,3,2,1};
for (int i=0; i<HTankindexArr1.Length; i++)
{
Console.Write(HTankindexArr1[i]+"|");
}
Console.WriteLine("");
foreach (int j in HTankindexArr1)
{
Console.Write(j+"|");
}
Console.WriteLine("");
}
复制数组的4种方法
static void Main(string[] args)
{
int[] nBKillNums= {15,21,0,0};
//
int[] nBKillNums1= (int[])nBKillNums.Clone();
int[] nBKillNums1= new int[nBKillNums.Length];
//nBKillNums.CopyTo(nBKillNums1,0);
Array.Copy(nBKillNums,nBKillNums1,nBKillNums1.Length);
for(int i=0;i!=nBKillNums1.Length;i++)
{
//nBKillNums1[i]=nBKillNums[i];
Console.Write(nBKillNums1[i]+"|");
}
Console.WriteLine("");
}
ArrayList集合
static void Main(string[] args)
{
int[] nAKillNums1={3,4,0,0};
ArrayList list=new ArrayList();
for(int i=0;i<nAKillNums1.Length;i++)
{
list.Add(nAKillNums1[i]);
}
list.Insert(1,11);
list.Remove(0);
list.RemoveAt(1);
list.RemoveRange(1,2);
IEnumerator enu=list.GetEnumerator();
while(enu.MoveNext()){
Console.Write(enu.Current+",");
}
Console.WriteLine("");
}
对数组元素进行升序排序、反转
static void Main(string[] args)
{
int[] A= {3,4,8,1};
Array.Sort(A);
for(int i=0;i<A.Length;i++)
{
Console.Write(A[i]+"|");
}
Console.WriteLine("");
Array.Reverse(A);
foreach(int j in A)
{
Console.Write(j+"|");
}
Console.WriteLine("");
}
chap7反射、后期绑定与attribute
7.1反射
System.Reflection命名空间
程序集System.Reflection.Assembly
类与结构System.Type
方法System.Reflection.MethodInfo
字段System.Reflection.FieldInfo
方法参数System.Reflection.ParameterInfo
7.2后期绑定
一般来说,我们将一个类的联系分为3类:完全在编译期创建的早期绑定,在编译器创建了部分联系的动态绑定以及在执行期创建的后期绑定。
程序集A的代码可以实例化并使用一个定义在程序集B中的类型,而该类型可能在A编译的时候并没有被引用。我们把这种类型的联系描述为后期绑定。
C++中只存在早期与动态绑定。
7.3attribute
7.4动态生成程序集并在运行中使用
chap10从C#2.0的角度看.NET2.0类型系统
10.1.5静态分配与动态分配的比较
C++与C#有一个一致的地方,那就是对象要么分配在线程栈上(我们称之为静态分配),要么分配在进程堆中(我们称之为动态分配)。
C++与C#的不同之处在于分配模式(静态或动态)选择的方式。
C++中对象的分配模式是由程序员自己选择的。
C#中对象的分配模式将取决于对象的实现方式。我们将看到,共有2种类型:值类型的实例使用静态分配,而引用类型的实例使用动态分配。
new操作符可以分配值类型的实例。但是这样分配的实例仍然是静态分配。这种情况下new操作符仅起到向构造函数传递参数的作用。
与C++不同,C#的静态分配必须用new操作符而不能直接向构造函数传递参数。
结构总是定义成值类型,类总是定义成引用类型
public class FightResultItem
{
public int nViewSitindex;
public int nJoyNum;
public int nKillNum;
public int nTankID;
public string TankName;
public int nPlayerAddedScore;
}
public List<FightResultItem> m_AFightResultItem=new List<FightResultItem>();
FightResultItem AItem=new FightResultItem();
AItem.nViewSitindex=AAttr.m_Sitindex;
AItem.nJoyNum=AAttr.m_Joyindex+1;
AItem.nKillNum=AAttr.m_KillNum;
AItem.nTankID=PlayerManager.s_Inst.GetTankindex2(AAttr.m_Joyindex)+1;
AItem.TankName=Tankconfig.s_Inst.m_data[AItem.nTankID].Name;
AItem.nPlayerAddedScore=(int)((float)nTotalAddedScore*kA*(float)AItem.nKillNum/nATotalKillNum);
m_AFightResultItem.Add(AItem);
10.8.5整数和字符串之间的转换
现有基本类型每个都提供了以下3个方法:
public static [相应的基本类型] Parse(string s),静态方法能够解析一个字符串,从中提取相应基本类型的值。
public bool [相应的基本类型] TryParse(string s,out [相应的基本类型]),静态方法能够解析一个字符串,从中提取相应基本类型的值,通过out参数返回。如果成功解析,该方法返回true,否则返回false。
public string ToString(),该方法将数值写成一个字符串。这个方法是Object类中ToString()方法的覆写版本。
int nAWinPoint = Judian.s_Inst.m_nAWinPoint;
int nBWinPoint = Judian.s_Inst.m_nBWinPoint;
m_TextAWinPoint.text=nAWinPoint.ToString();
m_TextBWinPoint.text=nBWinPoint.ToString();
【
整型转实型
C#关键字|对应CTS类型|大小
float|System.Single|32
int ResurgenceTime=10;
float fTriggerTime=System.Convert.ToSingle(ResurgenceTime);
】
10.12字符串
10.12.1 System.String类
不再延续传统的char *和char []的用法。
与C++ STL的字符串类型string最大的不同是C#的String类实例是不可改变的,即无法修改它们。
C++字符串必须以零结尾的要求在C#中已经不存在了。
C#的string关键字是System.String类的别名。该类的实例表示一个UNICODE标准编码的字符串。
String类声明为sealed,意味着其他类都无法从它派生。
10.12.2字符串字面常量
C#提供了两种类型的字符串字面常量。
标准字符串字面常量,与C++的字符串字面常量类似。
无转义字符串字面常量。
10.12.3无转义字符串字面常量
10.12.4使用字符串
方法(均为公有)|描述
10.12.5格式化字符串
string类的Format静态方法
print(string.Format("在线时被击杀了Joyindex={0},LifeNum={1},Heroindex={2}",Joyindex,LifeNum,Heroindex));
10.12.6 System.Text.StringBuilder类
提供直接对字符串进行操作的功能。
public System.Text.StringBuilder m_content = new System.Text.StringBuilder();
m_content.Length=0;
m_content.Append(string.Format("echo {0} : {1}{2}", chatMessage.errorCode, chatMessage.version, i++));
UnityEngine.Debug.LogError(m_content.ToString());
提供了如下属性(全部为公有非静态成员)。
Append,在字符串的结尾增加字符
chap13泛型
13.5.2typeof运算符与泛型
可以将typeof运算符作用在类型参数上,返回一个表示该类型参数当前所表示的值的Type类实例。
也可以将typeof运算符作用在泛型类型上,返回一个表示该类型参数当前所表示的一组值的Type类实例。
public int OnProcessPacket1(DataUnit dataUnit)
{
UnityEngine.Debug.LogError("OnProcessPacket1"+dataUnit.m_nCmd);
if (dataUnit.m_oBodyUnit != null) {
if(dataUnit.m_oBodyUnit.GetType() == typeof( chat.SignUpResponse ) )
{
UnityEngine.Debug.LogError("OnProcessPacket1---SignUpResponse");
chat.SignUpResponse chatMessage = (chat.SignUpResponse)dataUnit.m_oBodyUnit;
}
}
return 0;
}
14.2.9指针和数组
数组是System.Array类的实例,存储在被垃圾收集器所管理的托管堆上。
14.2.10固定数组
unsafe struct Foo {
public fixed int FixedArray[10];
public int Overflow;
}
14.2.11使用stackalloc关键字在栈上分配内存
int *array=stackalloc int[100];
for(int i=0;i<100;i++){
array[i]=i*i;
}
15.2数组
数组是分配在堆上而不是栈上的。但某些特殊情况下把数组分配在栈上是有可能的(参见14.2.10节)。
15.2.4初始化数组的项
C#允许写数组字面常量。
string[] strPlayerCardIDArr={"test1","test2","test3","test4","test5","test6","test7","test8"};