前言:最近在维护一个获取http接口的数据然后填充到Excel的工具,于是接触到了C#,总体感觉下来,C#关键字多,语法多,功能强大,LINQ感觉实现了一个C#版本的SQL。
基本结构
1
2
3
4
5
6
7
8
9
10
11
12
|
using System; /* 引入System命名空间 */
namespace HelloWorldApplication /* 命名空间声明 */
{
class HelloWorld /* 类 */
{
static void Main(string[] args) /* Main方法*/
{
Console.WriteLine("Hello World");
Console.ReadKey();
}
}
}
|
基本语法
项目构建
1
|
dotnet new console -o myApp
|
类型和变量
值类型
- 简单类型
- 有符号的整型: sbyte、short、int、long
- 无符号整型: byte、ushort、unit、ulong
- 字符: char
- 小数: float、double、decimal
- 布尔: bool
- 枚举类型: enum E{…}
- 结构类型: strcut S {…}
- null
引用类型
- 类
- object 所有类型的基类
- string
- Class C {…} 自定义类
- 接口类型 interface I {…}
- 数组类型 如int[]、 int[,]
- 委托类型 delegate int D(…)
引用类型
语句
1
2
3
4
|
if (...)
{}
else
{}
|
1
2
3
4
5
6
7
8
9
10
11
|
switch (n)
{
case 0:
...
break;
case 1:
...
break;
defaut:
...
}
|
1
2
3
4
|
do
{
...
} while (i > 100);
|
1
2
3
4
|
for (int i = 0; i < 100; i++;)
{
...
}
|
1
2
3
4
5
|
int[] l = {1, 2, 3};
foreach (int i in l)
{
Console.WriteLine(i);
}
|
- goto
- yield
- checked/unchecked
- throw
- try
1
2
3
4
5
6
7
8
9
10
|
try
{
...
}
catch (Exception e)
{
}
finally
{
}
|
类和对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
/* 申明 */
public class Point
{
public int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
}
/* 实例化 */
Point p1 = new Point(10, 20);
/* 继承 */
public class Point3D: Point
{
public int z;
public Point3D(int x, int y, int z):
base(x, y)
{
this.z = z;
}
}
|
成员
- 分为静态成员和实例成员,静态属于类,实例成员属于类实例
- 成员类型
- 常量
- 字段
- 方法
- 属性
- 索引器
- 事件
- 运算符
- 构造函数
- 终结器
- 类型
可访问性
- public 访问不受限制
- protectd 访问仅限于此类或派生类
- internal 仅限数于当程序集(exe、ddl等)
- protected internal 此类或派生类或当前程序集中的类
- private 仅限于此类
- private protected 此类或者当前程序集的派生类
类型参数(泛型)
1
2
3
4
5
6
7
8
|
/* 类名后用尖括号申明类型参数列表 */
public class Pair<TFirst, TSecond>
{
public TFirst First;
public TSecond Second;
}
Pair<int, string> pair = new Pair<int, string> {First = 1, Second = "two"}
|
字段
静态字段无论创建多少个类实例,都只有一个副本
1
2
3
4
5
6
|
public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
private byte r, g, b;
}
|
方法
参数
- 值参数: 传值, 可以指定默认值
- 引用参数: 传引用 使用ref修饰
1
2
3
4
5
6
7
8
9
|
static void Swap(ret int x, ret int y)
{
int temp = x;
x = y;
y = temp;
}
int i = 2, y = 10;
Swap(ref i, ref y);
|
1
2
3
4
5
6
7
|
static void Divide(int x, int y, out int result, out int remainder)
{
result = x / y;
remainer = x % y;
}
Diiden(10, 3, out int res, out int rem);
Console.WriteLine("{0} {1}", res, rem);
|
- 参数数组 使用params修饰,只能位于最后,只能是一维数组
1
2
3
4
5
6
|
public class Console
{
public static void Write(string fmt, params object[] args) { }
public static void WriteLine(string fmt, params object[] args) { }
// ...
}
|
方法主体和局部变量
静态和实例方法
使用static声明的方法是静态方法,静态方法只能访问静态成员
不使用static声明的方法是实例方法,实例方法可是访问静态和实例成员,可以使用this显示访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
class Entity
{
static int nextSerialNo;
int serialNo;
public Entity()
{
serialNo = nextSerialNo++;
}
public int GetSerialNo()
{
return serialNo;
}
public static int GetNextSerialNo()
{
return nextSerialNo;
}
public static void SetNextSerialNo(int value)
{
nextSerialNo = value;
}
}
|
虚方法、重载方法和抽象方法
- 虚方法 virtual修饰
- 抽象方法 abstract
- 重新方法 override
方法重载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
using System;
class OverloadingExample
{
static void F()
{
Console.WriteLine("F()");
}
static void F(object x)
{
Console.WriteLine("F(object)");
}
static void F(int x)
{
Console.WriteLine("F(int)");
}
static void F(double x)
{
Console.WriteLine("F(double)");
}
static void F<T>(T x)
{
Console.WriteLine("F<T>(T)");
}
static void F(double x, double y)
{
Console.WriteLine("F(double, double)");
}
public static void UsageExample()
{
F(); // Invokes F()
F(1); // Invokes F(int)
F(1.0); // Invokes F(double)
F("abc"); // Invokes F<string>(string)
F((double)1); // Invokes F(double)
F((object)1); // Invokes F(object)
F<int>(1); // Invokes F<int>(int)
F(1, 1); // Invokes F(double, double)
}
}
|
其他
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
public class MyList<T>
{
// Constant
const int defaultCapacity = 4;
// Fields
T[] items;
int count;
// Constructor
public MyList(int capacity = defaultCapacity)
{
items = new T[capacity];
}
// Properties
public int Count => count;
public int Capacity
{
get { return items.Length; }
set
{
if (value < count) value = count;
if (value != items.Length)
{
T[] newItems = new T[value];
Array.Copy(items, 0, newItems, 0, count);
items = newItems;
}
}
}
// Indexer
public T this[int index]
{
get
{
return items[index];
}
set
{
items[index] = value;
OnChanged();
}
}
// Methods
public void Add(T item)
{
if (count == Capacity) Capacity = count * 2;
items[count] = item;
count++;
OnChanged();
}
protected virtual void OnChanged() =>
Changed?.Invoke(this, EventArgs.Empty);
public override bool Equals(object other) =>
Equals(this, other as MyList<T>);
static bool Equals(MyList<T> a, MyList<T> b)
{
if (Object.ReferenceEquals(a, null)) return Object.ReferenceEquals(b, null);
if (Object.ReferenceEquals(b, null) || a.count != b.count)
return false;
for (int i = 0; i < a.count; i++)
{
if (!object.Equals(a.items[i], b.items[i]))
{
return false;
}
}
return true;
}
// Event
public event EventHandler Changed;
// Operators
public static bool operator ==(MyList<T> a, MyList<T> b) =>
Equals(a, b);
public static bool operator !=(MyList<T> a, MyList<T> b) =>
!Equals(a, b);
}
|
构造函数 : 和类名相同,无返回值
属性: 不指明存储位置,set和get设置读写属性
1
2
3
4
|
MyList<string> names = new MyList<string>();
names.Capacity = 100; // Invokes set accessor
int i = names.Count; // Invokes get accessor
int j = names.Capacity; // Invokes get accessor
|
索引器
事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class EventExample
{
static int changeCount;
static void ListChanged(object sender, EventArgs e)
{
changeCount++;
}
public static void Usage()
{
MyList<string> names = new MyList<string>();
names.Changed += new EventHandler(ListChanged);
names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
Console.WriteLine(changeCount); // Outputs "3"
}
}
|
数组
1
|
int a = new int[]{1,2,3}
|
- 数组中的元素均为同一种类型
- new运算指定了实例的长度,此长度不可变
- 默认值为0或null
- L.length访问长度
接口
定义了可有类或结构实现的成员,可以多重继承,类也可以实现多个接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
interface IControl
{
void Paint();
}
interface IDataBound
{
void BInd(BInd b);
}
public class EditBox: IContril, IDataBound
{
public void Paint() {}
public void Bind(Bind b) {}
}
|
类可以隐式转换成相应的接口类型
1
2
|
EditBox editBox = new EdixBox();
IControl control = eidBox;
|
委托
实现将方法作为参数传递
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
using System;
delegate double Function(double x);
class Multiplier
{
double factor;
public Multiplier(double factor)
{
this.factor = factor;
}
public double Multiply(double x)
{
return x * factor;
}
}
class DelegateExample
{
static double Square(double x)
{
return x * x;
}
static double[] Apply(double[] a, Function f)
{
double[] result = new double[a.Length];
for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
return result;
}
static void Main()
{
double[] a = {0.0, 0.5, 1.0};
double[] squares = Apply(a, Square);
double[] sines = Apply(a, Math.Sin);
Multiplier m = new Multiplier(2.0);
double[] doubles = Apply(a, m.Multiply);
}
}
|
可以使用匿名函数创建委托
1
|
double[] doubles = Apply(a, (double x) => x * 2.0);
|
参考