C# 核心基础(1) 持续更新
using System; namespace ConsoleApplicationCShape { class Program { static void Main(string[] args) { Console.WriteLine("Hello Wrox."); Console.ReadLine(); return; } } }
变量初始化
int i = 1; bool mBool = false; int x = 12, y = 12;
类型推断关键字 var
var name = "Aaron"; var age = 12; var isRabbit = false; Type nameType = name.GetType(); Type ageType = age.GetType(); Type isRabbitType = isRabbit.GetType(); Console.WriteLine("name is type " + nameType.ToString()); Console.WriteLine("age is type " + ageType.ToString()); Console.WriteLine("isRabbit is type " + isRabbitType.ToString()); Console.ReadLine();
输出
name is type System.String age is type System.Int32 isRabbit is type System.Boolean
- 变量必须初始化。否则,编译器就没有推断变量类型依据
- 初始化器不能为空。
- 初始化必须放在表达式中。
- 不能把初始化器设置为一个对象,除非在初始化器中创建一个新对象。
一旦声明了变量,推断出了类型,不能改变变量类型。
变量作用域
- 只要类在某个作用域内,其字段也在该作用域内。
- 局部变量存在于声明该变量的语句块或方法结束的右花括号之前的作用域内。
- 在for、while或类似语句中声明的局部变量存在于该循环体内。
局部作用域冲突
只要变量的作用域是程序的不同部分,就不会有问题,也不会产生多义性。注意,同名局部变量不能再同一作用域内声明两次。
int j = 0; for (int i = 0; i < 10; i++) { int j = 0; Console.WriteLine(i + j); }
for (int i = 0; i < 10; i++) { int j = 0; Console.WriteLine(i + j); } for (int i = 0; i < 10; i++) { int j = 0; Console.WriteLine(i + " " + j); }
字段和局部变量的作用域冲突
字段 (静态变量)
static int j = 20
局部变量
int j = 30
static int j = 20; static void Main(string[] args) { int j = 30; Console.WriteLine(j); Console.WriteLine(Program.j); Console.ReadLine(); }
常量
- 常量必须声明时初始化。执行值后,就不能再改写了。
- 常量的值必须能在编译时用于计算。因此,不能从一个变量中提取的值用来初始化常量。(如果一定要这样做,可以用 readonly 只读)
- 常量总是静态的,所以不能常量声明中包含修饰符 static
const int j = 20;
预定义数据类型
值类型和引用类型
C#数据类型分为 值类型 和 引用类型
值类型直接存储其值,引用类型存储对值得引用。
值类型存储在堆栈中,引用类型存储在托管堆上。
值类型
int x = 20; int j = 30;
引用类型
Vector x, y; x = new Vector(); x.X = 30; Console.WriteLine(x); y = x; y.X = 30; Console.WriteLine(y); Console.WriteLine(x);
输出
30,0 30,0 30,0
注意 我这里 Vector 只有在 System.Windows.WindowsBase 命名空间中,大家要测试引用类型时,需创建WPF程序。
要创建对象,须使用new 关键字。因为 x 和 y 引用同一对象,所以修改 x,也会影响 y 。当然值类型是不会有影响的。
CTS类型
C# 有15个预定定义类型,其中13个是值类型,2个引用类型(string 和 object)
8个整数类型 sbyte、short、int、long、byte、ushort、uint、ulong
2个浮点类型 float、double
1个高精度浮点数 128位 decimal
1个布尔类型 bool
1个单字符类型 char
2个预定义引用类型 object、string
声明 decimal
decimal d = 12.30M;
声明 char
char c = 'x';
声明 string
string str = "Hello world";
转义字符
string str1 = "C:\\Program Files (x86)\\ADSafe"; string str2 = @"C:\Program Files (x86)\ADSafe";
甚至包含换行符
string str2 = @"C:\Program Files (x86) \ADSafe"; Console.WriteLine(str2);
流控制
if
int intInput = Int32.Parse(Console.ReadLine()); if (intInput == 10) { Console.WriteLine("Input 10"); }else if (intInput == 20) { Console.WriteLine("Input 20"); } else { Console.WriteLine("Input Error"); } Console.ReadLine();
如果条件分支只有一条语句,就无须使用花括号:
if (intInput == 10) Console.WriteLine("Input 10");
switch
while (true) { int intInput = Int32.Parse(Console.ReadLine()); switch (intInput) { case 0: case 10: Console.WriteLine("Input 10"); break; case 20: Console.WriteLine("Input 20"); goto case 30; break; case 30: Console.WriteLine("Input 30"); break; default: Console.WriteLine("Input Error"); break; } }
break 结束当前循环
continue 退出当前迭代,进行下一轮迭代
循环
for
for (int i = 0; i < 10; i++) { Console.WriteLine(i); }
i++ ==> i = i + 1 ==> i += 1
while
int i = 0; while (i < 10) { i++; Console.WriteLine(i); }
do while
int i = 100; do { i++; Console.WriteLine(i); } while (i < 10);
foreach
int[] arr = new int[6] {1,2,3,4,5,6}; foreach (int value in arr) { Console.WriteLine(value); }
跳转语句 goto、break、continue、return
枚举
public enum TimeOfDay { Morning = 0, Afternoon = 1, Evening = 2 }
使用
TimeOfDay time = TimeOfDay.Afternoon; Console.WriteLine(time.ToString()); Console.WriteLine((int)time);
名称空间
namespace ConsoleApplicationCShape { namespace CustomerPhoneBookApp { class NamespaceExample { } } class Program { static void Main(string[] args) { } } }
using语句
using System; using System.Collections.Specialized;
名称空间的别名
using System; using System.Collections.Specialized; using CusNameSpace = MyNamespace; namespace MyNamespace { class Test { } } namespace ConsoleApplicationCShape { class Test { } class Program { static void Main(string[] args) { //不使用限定名向上搜索匹配的命名空间,查找不到会输出错误 Console.WriteLine(typeof(Test)); Console.WriteLine(typeof(CusNameSpace::Test)); Console.ReadLine(); } } }
全局命名空间
using System; using System.Collections.Specialized; class Test { } namespace ConsoleApplicationCShape { class Test { } class Program { static void Main(string[] args) { Console.WriteLine(typeof(Test)); Console.WriteLine(typeof(global::Test)); Console.ReadLine(); } } }
每个类都有个Type对象 this.GetType().Namespace;
Main方法
C#程序从Main开始执行的,这个方法必须是类或结构的静态方法,返回类型必须是 int 或 void。修饰符指定什么访问级别并不重要。
多个main方法
在编译C#时,在多个main方法是,需要指定Main方法所属类的全名,告诉程序的入口点。
csc DoubleMain.cs /main:Wrox.MathExample
给main传递参数
static void Main(string[] args) { for (int i = 0; i < args.Length; i++) { Console.WriteLine(args[i]); } Console.ReadLine(); }
输出
>ConsoleApplicationCShape.exe 1 2 z 1 2 z static void Main(string[] args)
有关编译 C# 文件的更多内容
csc /target 选项
- /t:exe 控制台应用程序 默认
- /t:library 带有清单的类库
- /t:moudle 没有清单的组件
- /t:winexe Windows应用程序
/out 选项
指定编译器生成的输出文件名
/reference 或 /r 引用程序集
csc /r:system.windows.forms.dll
示例
csc /t:library MathLibrary.cs
编译文件时
csc MathClient.cs /r:MathLibrary.dll
控制台 I/O
-
Console.WriteLine();
- Console.ReadLine();
格式化字符串
Console.WriteLine("{0}、{1}",100,200);
Console.WriteLine("{0,30}\n{1,30}", 100, 200);
{w,n} n 是参数索引,w是宽度值。
格式化字符串类型
- C 本地货币格式
- D 十进制,如果需要精度,前面加上0
- E 科学计数法格式,默认小数位数6 格式化字符串的大小写(e或E)指定指数符号的大小写
- F 浮点数类型,可以设置小数位数,可以为0
- G 普通格式
- N 数字格式,用逗号表示千分符如 32 767.44
- P 百分数格式
- X 十六进制格式
除了 e/E 之外,格式字符串都不需要考虑大小写。
本地货币格式,精度设置为两位小数
double d = 0.234; Console.WriteLine("{0, 9:C2}", d);
注释
// this is a single-line comment
/*
* This Comment
* spans mutiple lines.
*/
生成 注释XML 文档
/// <summary> /// 返回两位整数相加的值 /// </summary> /// <param name="x">X 整数值</param> /// <param name="y">Y 整数值</param> /// <returns>返回相加值</returns> public int Add(int x, int y) { return x + y; }
csc /t:library /doc:MathLibrary.xml MathLibrary.cs
C# 预处理指令
使用预处理指令可以境值编译器编译与额外功能相关的代码。还是可以提供调试信息的代码时,也可以用。
#define 和 #undef
#define 指定编译器名称符号
#undef 删除指定编译器名称符号
#if、#elif、#else、#endif
#define ENTERPRISE using System; using System.Collections.Specialized; namespace ConsoleApplicationCShape { class Program { static void Main(string[] args) { #if ENTERPRISE && W2K == false Console.WriteLine("Hello"); #endif Console.ReadLine(); } } }
#warning 和 #error
如果编译器遇到 #warning 会给用户显示 #warning指令后面的文本。
如果遇到 #error,显示后面的文本,作为编译器错误消息,退出编译,不会生成IL代码(.net 中间代码)。
#if ENTERPRISE #warning This is a warning #endif #error This is a error
然后可以在VS2015的错误列表中看到。
#region 和 #endregion
#region 和 #endregion 把一段代码给定给定名称一个块。
#region 这是一个输入文件块 Console.ReadLine(); #endregion
然后可以折叠这块代码
#line
改变编译器在警告或错误信息中显示的文件名和行号信息。
#line 2 "Core.cs" #warning 警告 #error This is Error
#pragma
抑制或还原指定的编译警告。
如下面 禁止"字段未使用警告"
#pragma warning disable 15 static void Main(string[] args) { int neverUsedField; Console.ReadLine(); } #pragma warning restore 15