《csharp高级编程》 学习笔记 第二章 csharp基础

第二章 csharp基础
2.3.1 变量的初始化
对于变量的初始化c#的编译器更加严厉。大多数现代编译器把没有初始化标记为警告,但csharp编译器会标记为错误。
csharp有两个确保变量在使用前进行初始化的方法:
1.变量是类或结构中的字段,如果没有显示初始化,创建这些变量时,其值默认是0;
2 方法的局部变量必须在代码中显示初始化后才能在语句中使用。

考虑下面的语句:
Something objSomething;
在C++中,上面的代码会在堆栈中创建Something 类的一个实例。
在C#中,这行代码仅会为Something 对象创建一个引用,但这个引用还没有指向任何对象。对该变量调用方法或属性会导致错误。
在C#中实例化一个引用对象需要使用new 关键字。
如上所述,创建一个引用,使用new 关键字把该引用指向存储在堆上的一个对象:
objSomething = new Something(); // This creates a Somethingon the heap

2.3.2 类型推断
类型推断使用var关键字。编译器会根据变量的初始化推断数据的类型。
故下面两句代码等价:
int someNumber=0;
var someNumber=0;
2.3.3 变量的作用域

作用域变量冲突的原则和c++同理。
2.3.4 常量
const int a=100;
相对比c++常量,csharp的常量用途少了许多。
c++中有常量指针,常量方法,常量参数等。
而在csharp中只能把局部变量和字段声明为常量。
注意常量总是静态的,不必在常量声明中包含修饰符static。

2.4 预定义数据类型
2.4.1 值类型和引用类型
前者存储在堆栈中,后者存储在托管堆上。
Vector x, y;
x = new Vector ();
x.Value = 30; // Value is a field defined in Vector class
y = x;
Console.WriteLine(y.Value);
y.Value = 50;
Console.WriteLine(x.Value);
这个要理解清楚其实也挺简单,即类似c++的指针,执行完这段代码后只有一个vector对象,因为我们只new了一次。
两个引用类型x,y都指向这同一个对象。
因此上面代码显示30和50。

c#变量是值还是引用仅取决于其数据类型。如int总是值类型,而大多数更复杂的c#数据类型,包括我们自己声明的类都是引用类型。
2.4.2 CTS 类型
csharp任课的基本预定义类型是内置于.NET framework中。
如果在声明一个int,实际上是声明System.Int32的一个实例。
这表示在语法上,可以把所有的基本数据类型看做是支持某些方法的类。
例如 int i转化为string的代码为:
string s=i.ToString();

2.4.3预定义的值类型
需要注意的c#中所有的数据类型都以与平台无关的方式定义。
如int 始终是32位带符号整数。这一点不同于c++。
同时,在强调类型的安全性时,c#认为byte和char完全不同,之间的编程转换必须显示写出。

decimal类型
表示精度更大的浮点数,是专用与进行财务计算的类型。
注意,decimal类型不是基本类型,所以在计算时使用该类型会有性能损失。
decimal d=12.30m
不加后缀则默认为double

bool类型
和c++不同的是不能和整数值相互隐式转换。
char类型
表示一个16 位的(Unicode)字符

2.4.4 预定义的引用类型

名称CTS 类说明
object System.Object 根类型,CTS 中的其他类型都是从它派生而来的(包括值类型)
string System.String Unicode 字符串
object类型就是最终的父类型,所有内置类型和用户定义的类型都从它派生而来。
这样object可以用于两个目的:
1.可以使用object引用绑定任何子类型的对象。
2.object类型执行许多一般用途的基本方法,包括Equals(),ToString()。

对于string这个引用类型。
要注意他不是一般的引用类型,和上面举例过的vector不全相同。
比如:
string s1="a string";
string s2=s1;
s1="another string";
此时s1是another string
s2是a string

这实际上是运算符重载的结果。


2.5 流控制
大部分和c++一样。
需要注意的如下:
1.switch 的case 后面可以把字符串用作测试变量。
2.foreach循环
foreach(int temp in arrayOfInts)
{
Console.WriteLine(temp);
}
也可以换成foreach(var temp in arrayOfInts)...
注意,foreach循环不能改变集合中各项的值,如下面代码不会编译:
foreach(int temp in arrayOfInts)
{
temp++;
Console.WriteLine(temp);
}
如果需要迭代集合中的各项,并改变其值,就用哪个使用for循环。
我的理解是foreach对集合的特殊保护作用。
2.6 枚举
csharp枚举要比c++枚举强大得多。
因为它可以得益于.NET的systm.enum基类
public enum TimeOfDay
{
Morning = 0,
Afternoon = 1,
Evening = 2
}
TimeOfDay.Morning 返回数字0

可以获取枚举的字符串表示,例如使用前面的TimeOfDay 枚举:
TimeOfDay time = TimeOfDay.Afternoon;
Console.WriteLine(time.ToString());

2.7 数组
//create a new array of 32 ints;
int [] integers =new int [32];
*所有的数组都是引用类型。
csharp的数组语法非常灵活。声明数组时可以不进行初始化(其实类似指针,c++程序员应该很容易理解),这样以后就可以在程序中动态指定其大小。
int[] integers;
integers =new int [32];
int numElements=integers.Length;
//because integers is any referrence to an array;

2.8 命名空间
命名空间是一种逻辑组合,而不是物理组合。
注意不允许在另一个嵌套的命名空间中声明多部分的命名空间。
命名空间与程序集无关。同一个程序集中可以有不同的命名空间,也可以在不同的程序集中定义同一个命名空间中的类型。

2.8.1 using 语句
注意,不要吧命名空间与c++风格的头文件相混淆。using语句在这些文件之间并没用建立物理链接。c#也没用对应与c++头文件的部分。
2.8.2 命名空间的别名
using关键字的另一用途就是给类和命名空间指定别名。
using alias=NamespaceName;
using Introduction=Wrox.ProCSharp.Basics;

2.9 Main()方法
2.9.1多个Main()方法
在编译csharp控制台或windows应用程序时,默认情况会出编译错误。
2.9.2给Main()传递参数

2.10 有关编译csharp文件的更多内容
2.11 控制台I/O
2.12 使用注释
2.12.1 源文件中的内部注释
2.12.2 xml文档说明
根据特定的注释自动创建xml格式的文档说明。
这些注释都是单行注释,但都以三个斜杠///开头。
在这些注释中,可以把包含类型和类型成员的文档说明的xml标示符放在代码中。
// Math.cs
namespace Wrox.ProCSharp.Basics
{
///<summary>
/// Wrox.ProCSharp.Basics.Math class.
/// Provides a method to add two integers.
///</summary>
public class Math
{
///<summary>
/// The Add method allows us to add two integers
///</summary>
///<returns>Result of the addition (int)</returns>
///<param name="x">First number to add</param>
///<param name="y">Second number to add</param>
public int Add(int x, int y)
{
return x + y;
}
}
}
csharp编译器可以把xml元素从特定的注释中提取出来,并使用它们生成一个xml文件。
如果xml注释没有生成格式正确的xml文档,编译器就生成一个错误。
2.13 csharp预处理器指令
2.13.1 #define和#undef
#define DEBUG 告诉编译器存在给定名称的符号,但这个符号没有真正的值,只是存在而已。
#undef 正好相反,删除符号的定义
#undef DEBUG
如果该符号不存在,#undef就没有任何作用。
同理,如果符号存在,#define也不起作用。
2.13.2 #if,#elif,#else 和#endif
这些指令告诉编译器是否要编译某个代码块。
条件编译:
#if DEBUG
Console.WriteLine("x is " + x);
#endif
只有定义了DEBUG后才会编译console.writeline.....这行代码
#if 和#elif 还支持一组逻辑运算符!、==、!=和||。如果符号存在,就被认为是true,否则为false,
例如:
#if W2K && (ENTERPRISE==false) // if W2K is defined but ENTERPRISE isn't

2.13.3 #warning 和 #error
另外两个非常有用的预处理器指令是#warning 和#error,当编译器遇到它们时,会分别产生警告或错误。
如果编译器遇到#warning 指令,会给用户显示#warning 指令后面的文本,之后编译继续进行。
如果编译器遇到#error 指令,就会给用户显示后面的文本,作为一个编译错误信息,然后会立即退出编译,不会生成IL 代码。
使用这两个指令可以检查#define 语句是不是做错了什么事,使用#warning 语句可以让自己想起做过什么事:
#if DEBUG && RELEASE
#error "You've defined DEBUG and RELEASE simultaneously! "
#endif
#warning "Don't forget to remove this line before the boss tests
the code! "
Console.WriteLine("*I hate this job*");
2.13.4 #region 和 #endregion
可以更好的布局。
2.13.5 #line
不常用
2.13.6 #pragma
该指令可以抑制或恢复制定的编译警告。

2.14 csharp 编程规则



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值