参考资料:
https://github.com/derekbanas/C-Sharp-Course/tree/main
参考文档:
https://www.tutorialsteacher.com/csharp/csharp-version-history
01 - Data
字符串转化成其他类型:
1
2
3bool boolFromStr = bool.Parse("true");
int intFromStr = int.Parse("123");
double dblFromStr = double.Parse("3.1415");其他类型转化成字符串:
1
string str = dblFromStr.ToString();
格式转换
可以使用的参数有:货币表示、填充、精确到几位小数、逗号隔开
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15//货币
//Currency : ¥23.45
Console.WriteLine("Currency : {0:c}", 23.455);
//向前填充
//Pad with 0s : 0023
Console.WriteLine("Pad with 0s : {0:d4}", 23);
//精确到三位小数
//3 Decimals : 23.456
Console.WriteLine("3 Decimals : {0:f3}", 23.45555);
//逗号隔开
//Commmas : 2,300.0000
Console.WriteLine("Commmas : {0:n4} ", 2300);
//逗号隔开
//Commmas : 230,000,000
Console.WriteLine("Commmas : {0:n0} ", 230000000);字符串操作
字符串操作包括:取大小、是否包含、索引位置、删除、插入、替换、对比
填充、全部大写、全部小写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22string randString = "This is a string";
Console.WriteLine("String Length : {0}", randString.Length);
Console.WriteLine("String Contains is : {0}", randString.Contains("is"));
Console.WriteLine("Index of is : {0}", randString.IndexOf("is"));
Console.WriteLine("Remove String : {0}", randString.Remove(10, 6));
Console.WriteLine("Insert String : {0}", randString.Insert(10, "short "));
Console.WriteLine("Replace String : {0}", randString.Replace("string", "sentence"));
Console.WriteLine("Compare A to B : {0}", String.Compare("A", "B", StringComparison.OrdinalIgnoreCase));
Console.WriteLine("-------------------");
Console.WriteLine("A = a : {0}", String.Equals("A", "a", StringComparison.OrdinalIgnoreCase));
Console.WriteLine("Pad Left : {0}", randString.PadLeft(20, '.'));
Console.WriteLine("Pad Right : {0}", randString.PadRight(20, '.'));
// Trim whitespace
Console.WriteLine("Trim : {0}", randString.Trim());
Console.WriteLine("Uppercase : {0}", randString.ToUpper());
Console.WriteLine("Lowercase : {0}", randString.ToLower());
string newString = String.Format("{0} saw a {1} {2} in the {3}", "Paul", "rabbit", "eating", "field");
Console.Write(newString + "\n");
Console.WriteLine(@"Exactly what I type\n");结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16String Length : 16
String Contains is : True
Index of is : 2
Remove String : This is a
Insert String : This is a short string
Replace String : This is a sentence
Compare A to B : -1
-------------------
A = a : True
Pad Left : ....This is a string
Pad Right : This is a string....
Trim : This is a string
Uppercase : THIS IS A STRING
Lowercase : this is a string
Paul saw a rabbit eating in the field
Exactly what I type\n数组操作
支持多种类型:基础数据类型、未定义类型、多种数据类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14int[] favNums = new int[3];
favNums[0] = 23;
Console.WriteLine("favNum 0 : {0}", favNums[0]);
string[] customers = { "Bob", "Sally", "Sue" };
var employees = new[] { "Mike", "Paul", "Rick" };
object[] randomArray = { "Paul", 45,1.234 };
Console.WriteLine("randomArray 0 : {0}", randomArray[0].GetType());
Console.WriteLine("Array Size : {0}", randomArray.Length);
for (int j = 0; j < randomArray.Length; j++)
{
Console.WriteLine("Array : {0}: Value : {1}", j, randomArray[j]);
}二维数组的操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16Console.WriteLine("---------------------------");
string[,] custNames = new string[2, 2]{{ "Bob", "Sam"}, { "Sally", "Smith" }};
Console.WriteLine("MD Value : {0}", custNames.GetValue(1,0));
for (int j = 0; j < custNames.GetLength(0); j++)
{
for (int k = 0; k < custNames.GetLength(0); k++)
{
Console.WriteLine("{0} ",custNames[j, k]);
}
Console.WriteLine();
}
int[] randNums = { 3, 4, 1, 2 };
PrintArray(randNums, "ForEach");数组方法
包括排序、反转、索引、设置值、复制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20Console.WriteLine("---------------------------");
Array.Sort(randNums);
Array.Reverse(randNums);
Console.WriteLine("1 at index: {0}", Array.IndexOf(randNums, 1));
randNums.SetValue(0, 1);
int[] srcArray = { 1, 2, 3 };
int[] desArray = new int[2];
int startId = 0;
int length = 2;
Array.Copy(srcArray, startId, desArray, 0, length);
PrintArray(desArray, "Copy");
Array anotherArray = Array.CreateInstance(typeof(int), 10);
srcArray.CopyTo(anotherArray, 5);
foreach (int m in anotherArray)
{
Console.WriteLine("CopyTo : {0} ", m);
}C#中能用到的条件语句有
- if/else
- 三元表达式
- switch
- Equals函数
随机数的使用
1
2Random random = new Random();
int[] rand = random.Next(1, 11);这段代码可以生成1~10之间的随机数
时间
这个例子中有两种类型:DateTime,TimeSpan,以下是他们的用例
- DateTime
1
2
3
4
5
6
7DateTime awesomeDate = new DateTime(1974, 12, 21);
Console.WriteLine("Day of Week : {0}", awesomeDate.DayOfWeek);
awesomeDate = awesomeDate.AddDays(4);
awesomeDate = awesomeDate.AddMonths(1);
awesomeDate = awesomeDate.AddYears(1);
Console.WriteLine("New Date : {0}", awesomeDate.Date);- TimeSpan
1
2
3
4
5TimeSpan lunchTime = new TimeSpan(12, 30, 0);
lunchTime = lunchTime.Subtract(new TimeSpan(0, 15, 0));
lunchTime = lunchTime.Add(new TimeSpan(1, 0, 0));
Console.WriteLine("New Time : {0}", lunchTime.ToString());枚举
可以指定类型,可以设置默认值,之后的值都是前面的加一
1
2
3
4
5
6
7
8
9
10
11
12
13
14enum CarColor : byte
{
Orange = 1,
Blue,
Green,
Red,
Yellow
}
static void PaintCar(CarColor cc)
{
Console.WriteLine("The car was painted {0} with the code {1}",
cc, (int)cc);
}
02 - Exception Handeling
使用try和catch来处理可能发生异常的地方。
1 | public class Program |
03 - StringBuilder
1 | StringBuilder sb = new StringBuilder("Random Text"); |
04 - Function
static:不用实例化,可以直接调用
ref:可以引用变量,传递参数的地址,使用ref前必须对变量赋值
out:out是传递返回的值,退出函数时所有out引用的变量都要赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public static void Swap(ref int num1, ref int num2)
{
int temp = num1;
num1 = num2;
num2 = temp;
}
static void Main(string[] args)
{
int num = 0;
int num2 = 1;
Console.WriteLine("Before Swap num1 : {0} num2 : {1}", num, num2);
Swap(ref num, ref num2);
Console.WriteLine("After Swap num1 : {0} num2 : {1}", num, num2);
}params:可以不限制地传入参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public static double GetSumMore(params double[] nums)
{
double sum = 0;
foreach (double num in nums)
{
sum += num;
}
return sum;
}
static void Main(string[] args)
{
Console.WriteLine("1 + 2 + 3 + 4 + 5 + 6 = {0} ", GetSumMore(1, 2, 3, 4, 5, 6));
}使用定义的参数就可以无需按需传入参数
1
2
3
4
5
6
7
8
9
10static void PrintInfo(string name, int zipCode)
{
Console.WriteLine("{0} lives in the zip code {1}", name, zipCode);
}
static void Main(string[] args)
{
PrintInfo(zipCode: 15147,name: "Derek Banas");
}函数重载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19static double GetSum2(double x = 1, double y = 1)
{
return x + y;
}
static double GetSum2(string x = "1", string y = "1")
{
double dblX = Convert.ToDouble(x);
double dblY = Convert.ToDouble(y);
return dblX + dblY;
}
static void Main(string[] args)
{
Console.WriteLine("5.0 + 4.0 = {0}", GetSum2(5.0, 4.5));
Console.WriteLine("5 + 4 = {0}", GetSum2(5, 4));
Console.WriteLine("5 + 4 = {0}", GetSum2("5", "4"));
}
05 - Class
internal:只能在程序集中可见
static:
- 变量:所有实例共享一个变量
- 函数:无需实例化即可使用的函数
类的初始化方式
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
79class Animal
{
private string name;
private string sound;
public const string SHELTER = "Derek's Home for Animals";
public readonly int idNum;
public void MakeSound()
{
Console.WriteLine("{0} says {1}",
name, sound);
}
public Animal()
: this("No Name", "No Sound") { }
public Animal(string name)
: this(name, "No Sound") { }
public Animal(string name,
string sound)
{
SetName(name);
Sound = sound;
NumOfAnimals = 1;
Random rnd = new Random();
idNum = rnd.Next(1, 2147483640);
}
public void SetName(string name)
{
if (!name.Any(char.IsDigit))
{
this.name = name;
}
else
{
this.name = "No Name";
Console.WriteLine("Name can't contain numbers");
}
}
public string GetName()
{
return name;
}
public string Sound
{
get { return sound; }
set
{
if (value.Length > 10)
{
sound = "No Sound";
Console.WriteLine("Sound is too long");
}
else
{
sound = value;
}
}
}
public string Owner { get; set; } = "No Owner";
public static int numOfAnimals = 0;
public static int NumOfAnimals
{
get { return numOfAnimals; }
set { numOfAnimals += value; }
}
}
06 - Abstract Class
如果你想定义不被实例化的类。在这种情况下,可以使用抽象类。
基类:
1 | abstract class Shape |
子类:
1 | class Circle : Shape |
基类的实例可以存储子类:
1 | Shape[] shapes = {new Circle(5), new Rectangle(4,5)}; |
07 - Interface
接口类,其中的方法需要被实现
以下是一个简单的例子:
接口:
1
2
3
4
5
6
7
8interface IDrivable
{
int Wheels { get; set; }
double Speed { get; set; }
void Move();
void Stop();
}实现类:
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
28class Vehicle : IDrivable
{
public string Brand { get; set; }
public Vehicle(string brand = "No Brand",
int wheels = 0,
double speed = 0)
{
Brand = brand;
Wheels = wheels;
Speed = speed;
}
public double Speed { get; set; }
public int Wheels { get; set; }
public void Move()
{
Console.WriteLine($"The {Brand} Moves Forward at {Speed} MPH");
}
public void Stop()
{
Console.WriteLine($"The {Brand} Stops");
Speed = 0;
}
}
或者这样使用
接口:
1
2
3
4
5
6
7interface IElectronicDevice
{
void On();
void Off();
void VolumeUp();
void VolumeDown();
}1
2
3
4
5interface ICommand
{
void Execute();
void Undo();
}实现类:
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
26class Television : IElectronicDevice
{
public int Volume { get; set; }
public void Off()
{
Console.WriteLine("The TV is Off");
}
public void On()
{
Console.WriteLine("The TV is On");
}
public void VolumeDown()
{
if (Volume != 0) Volume--;
Console.WriteLine($"The TV Volume is at {Volume}");
}
public void VolumeUp()
{
if (Volume != 100) Volume++;
Console.WriteLine($"The TV Volume is at {Volume}");
}
}1
2
3
4
5
6
7class TVRemote
{
public static IElectronicDevice GetDevice()
{
return new Television();
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class PowerButton : ICommand
{
IElectronicDevice device;
public PowerButton(IElectronicDevice device)
{
this.device = device;
}
public void Execute()
{
device.On();
}
public void Undo()
{
device.Off();
}
}使用:
1
2
3
4
5
6
7
8
9
10static void Main(string[] args)
{
IElectronicDevice TV = TVRemote.GetDevice();
PowerButton powBut = new PowerButton(TV);
powBut.Execute();
powBut.Undo();
powBut.Execute();
powBut.Undo();
}
08 - Collections
需要引入以下依赖:
1 | using System.Collections; |
C#中有以下几种类型的集合
- ArrayList
- List
- SortedList
- Dictionary
- Hashtable
- Stack
- Queue
ArrayList
可以存储多种数据结构的容器
1 |
|
Dictionary
字典,存储一对键值,
1 |
|
Queue
1 |
|
Stack
1 |
|
09 - Generic
类的泛型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15internal class Animal
{
public string Name { get; set; }
public Animal(string name)
{
Name = name;
}
public static void GetSum<T>(ref T num1, ref T num2)
{
double dblx = Convert.ToDouble(num1);
double dbly = Convert.ToDouble(num2);
Console.WriteLine($"{dblx} + {dbly} = {dblx + dbly}");
}
}结构体的泛型
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
31public struct Rectangle<T>
{
private T width;
private T height;
public T Width
{
get { return width; }
set { width = value; }
}
public T Height
{
get { return height; }
set { height = value; }
}
public Rectangle(T w, T h)
{
width = w;
height = h;
}
public string GetArea()
{
double dlbWidth = Convert.ToDouble(Width);
double dlbHeight = Convert.ToDouble(Height);
return String.Format($"{Width} * {Height} = {dlbWidth * dlbHeight}");
}
}调用
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
30static void Main(string[] args)
{
List<Animal> animalList = new List<Animal>();
List<int> intList = new List<int>();
intList.Add(24);
animalList.Add(new Animal("Dog"));
animalList.Add(new Animal("Cat"));
animalList.Add(new Animal("Bird"));
animalList.Insert(1, new Animal("Duck"));
animalList.RemoveAt(1);
Console.WriteLine("Num of Animals : {0}", animalList.Count);
foreach(Animal animal in animalList)
{
Console.WriteLine(animal.Name);
}
int x = 5, y = 4;
Animal.GetSum<int>(ref x, ref y);
string strX = "5", strY = "4";
Animal.GetSum<string>(ref strX, ref strY);
Rectangle<int> rec1 = new Rectangle<int>(20, 50);
Console.WriteLine(rec1.GetArea());
Rectangle<string> rec2 = new Rectangle<string>("20", "50");
Console.WriteLine(rec2.GetArea());
}
10 - Delegates
委托:如果我们想要将一个函数作为参数传递,C# 如何处理回调函数或事件处理程序?答案是 - 委托。 委托是一种引用类型数据类型,它定义了方法的签名。您可以像其他数据类型一样定义委托的变量,它可以引用与委托相同签名的任何方法。
在使用委托时涉及三个步骤:
- 声明一个委托
- 设置目标方法
- 调用委托
可以使用 delegate 关键字后跟函数签名来声明委托,如下所示。
1 | public delegate void MyDelegate(string msg); |
以下是一个使用委托的例子:
函数:
1
2
3
4
5
6
7
8
9
10
11public delegate void Arithmetic(double num1, double num2);
public static void Add(double num1, double num2)
{
Console.WriteLine($"{num1} + {num2} = {num1 + num2}");
}
public static void Subtract(double num1, double num2)
{
Console.WriteLine($"{num1} - {num2} = {num1 - num2}");
}调用:
1
2
3
4
5
6
7
8
9
10Arithmetic add, sub, addSub;
add = new Arithmetic(Add);
sub = new Arithmetic(Subtract);
addSub = add + sub;
Console.WriteLine($"Add {6} & {10}");
add(6, 10);
Console.WriteLine($"Add & Subtract {10} & {4}");
addSub(10, 4);
11 - Lambda
Basic
1
2doubleIt doubleIt = x => x * 2;
Console.WriteLine($"5 * 2 = {doubleIt(5)}");Where
条件判断
1
2
3
4
5
6
7
8
9List<int> numList = new List<int> { 1, 9, 2, 6, 3 };
var evenList = numList.Where(a => a % 2 == 0).ToList();
foreach (var j in evenList)
Console.WriteLine(j);
var rangeList = numList.Where(x => (x > 2) || (x < 9)).ToList();
foreach (var k in rangeList)
Console.WriteLine(k);生成列表
1
2
3
4
5
6
7
8List<int> flipList = new List<int>();
int i = 0;
Random rnd = new Random();
while (i < 100)
{
flipList.Add(rnd.Next(1, 3));
i++;
}条件判断
1
2
3
4
5
6
7
8
9
10
11Console.WriteLine("Heads : {0}",
flipList.Where(a => a == 1).ToList().Count());
Console.WriteLine("Tails : {0}",
flipList.Where(a => a == 2).ToList().Count());
// Find all names starting with s
var nameList = new List<string> { "Doug", "Sally", "Sue" };
var sNameList = nameList.Where(x => x.StartsWith("S"));
foreach (var m in sNameList)
Console.WriteLine(m);Select
1
2
3
4
5
6var oneTo10 = new List<int>();
oneTo10.AddRange(Enumerable.Range(1, 10));
var squares = oneTo10.Select(x => x * x);
foreach (var l in squares)
Console.WriteLine(l);Zip
1
2
3
4
5
6
7var listOne = new List<int>(new int[] { 1, 3, 4 });
var listTwo = new List<int>(new int[] { 4, 6, 8 });
var sumList = listOne.Zip(listTwo, (x, y) => x + y).ToList();
foreach (var n in sumList)
Console.WriteLine(n);Aggregate
1
2
3var numList2 = new List<int>() { 1, 2, 3, 4, 5 };
Console.WriteLine("Sum : {0}",
numList2.Aggregate((a, b) => a + b));Average
1
2
3
4var numList3 = new List<int>() { 1, 2, 3, 4, 5 };
Console.WriteLine("AVG : {0}",
numList3.AsQueryable().Average());All
1
2
3
4var numList4 = new List<int>() { 1, 2, 3, 4, 5 };
Console.WriteLine("All > 3 : {0}",
numList4.All(x => x > 3));Any
1
2
3
4var numList5 = new List<int>() { 1, 2, 3, 4, 5 };
Console.WriteLine("Any > 3 : {0}",
numList5.Any(x => x > 3));Distinct
去掉重复项,输出独立结果
1
2
3
4var numList6 = new List<int>() { 1, 2, 3, 2, 3 };
Console.WriteLine("Distinct : {0}",
string.Join(", ", numList6.Distinct()));Except
1
2
3
4
5var numList7 = new List<int>() { 1, 2, 3, 2, 3 };
var numList8 = new List<int>() { 3 };
Console.WriteLine("Except : {0}",
string.Join(", ", numList7.Except(numList8)));Intersect
1
2
3
4
5var numList9 = new List<int>() { 1, 2, 3, 2, 3 };
var numList10 = new List<int>() { 2, 3 };
Console.WriteLine("Intersect : {0}",
string.Join(", ", numList9.Intersect(numList10)));
12 - IEnumerator
很多时候,我们需要循环遍历一个匿名类型的类或列表集合。C# 语言的 IEnumerable 接口是其中一个最好的功能,用于循环遍历集合。
C# 中的 IEnumerable 是一个接口,定义了一个方法 GetEnumerator,该方法返回一个 IEnumerator 接口。这允许对集合进行只读访问,然后实现 IEnumerable 接口的集合可以在 for-each 语句中使用。
子类
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
27internal class AnimalFarm : IEnumerable
{
private List<Animal> m_AnimalList = new List<Animal>();
public AnimalFarm(List<Animal> animal)
{
m_AnimalList = animal;
}
public AnimalFarm() { }
public Animal this[int index]
{
get { return m_AnimalList[index]; }
set { m_AnimalList.Insert(index, value); }
}
public int Count
{
get { return m_AnimalList.Count; }
}
public IEnumerator GetEnumerator()
{
return m_AnimalList.GetEnumerator();
}
}遍历
1
2
3
4
5
6
7
8
9
10AnimalFarm animalFarm = new AnimalFarm();
animalFarm[0] = new Animal("Cat");
animalFarm[1] = new Animal("Dog");
animalFarm[2] = new Animal("Bird");
animalFarm[3] = new Animal("Duck");
foreach(Animal animal in animalFarm)
{
Console.WriteLine(animal.Name);
}
13 - Operator Overloading
本章包括运算符重载以及方法重载
运算符重载
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
45public static Box operator + (Box box1, Box box2)
{
Box box = new Box()
{
Length = box1.Length + box2.Length,
Width = box1.Width + box2.Width,
Breadth = box1.Breadth + box2.Breadth
};
return box;
}
public static Box operator - (Box box1, Box box2)
{
Box box = new Box()
{
Length = box1.Length - box2.Length,
Width = box1.Width - box2.Width,
Breadth = box1.Breadth - box2.Breadth
};
return box;
}
public static bool operator ==(Box box1, Box box2)
{
if ((box1.Length == box2.Length) &&
(box1.Width == box2.Width) &&
(box1.Breadth == box2.Breadth))
{
return true;
}
return false;
}
public static bool operator !=(Box box1, Box box2)
{
if ((box1.Length != box2.Length) ||
(box1.Width != box2.Width) ||
(box1.Breadth != box2.Breadth))
{
return true;
}
return false;
}方法重载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public override string ToString()
{
return String.Format("Box with Height : {0} Width : {1} and Breadth : {2}",
Length, Width, Breadth);
}
public static explicit operator int(Box b)
{
return (int)(b.Length + b.Width + b.Breadth) / 3;
}
public static implicit operator Box(int i)
{
return new Box(i, i, i);
}调用
1
2
3
4
5
6
7
8Box box1 = new Box(2, 3, 4);
Box box2 = new Box(5, 6, 7);
Box box3 = box1 + box2;
Console.WriteLine($"Box 3 : {box3}");
Console.WriteLine($"Box int : {(int)box3}");
Box box4 = (Box)4;
Console.WriteLine($"Box 4 : {box4}");
需要注意的是方法重载中使用到了explicit和implicit,在 C# 中,使用隐式和显式运算符进行数据类型转换。
- 隐式运算符用于在转换时无需用户干预的情况下将一种数据类型转换为另一种数据类型。
- 显式运算符用于在转换可能导致数据丢失或无法保证成功时进行显式用户干预。
当转换无需数据丢失时,通常首选使用隐式运算符。隐式运算符用于使代码更简洁、易读。隐式运算符还用于经常执行的转换,例如:
1 | int num1 = 10; |
当转换可能导致数据丢失或无法保证成功时,通常首选使用显式运算符,例如:
1 | double num1 = 10.5; |
在之前的方法重载中,由于double往int重载会损失精度,因此使用显示运算符explicit
而后面的例子中,由于使用int作为参数生成一个Box对象,不会发生数据损失,因此使用隐式运算符implicit
14 - Anonymous Types
匿名类型
1
2var shopkins = new { Name = "Shopkins", Price = 4.99 };
Console.WriteLine("{0} cost ${1}", shopkins.Name, shopkins.Price);匿名类型数组
1
2
3
4
5
6
7
8
9
10
11var toyArray = new[]
{
new { Name = "Yo-Kai Pack", Price = 4.99 },
new { Name = "Legos", Price = 9.99 }
};
foreach (var item in toyArray)
{
Console.WriteLine("{0} costs ${1}", item.Name, item.Price);
}
15 - LINQ
语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称。 数据查询历来都表示为简单的字符串,没有编译时类型检查或 IntelliSense 支持。 此外,需要针对每种类型的数据源了解不同的查询语言:SQL 数据库、XML 文档、各种 Web 服务等。 借助 LINQ,查询成为了最高级的语言构造,就像类、方法和事件一样。
Data
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
44Animal[] animalList = new[]
{
new Animal{ Name = "German Shepherd", Height = 25, Weight = 77, AnimalID = 1 },
new Animal{ Name = "Chihuahua", Height = 7, Weight = 4.4, AnimalID = 2 },
new Animal{ Name = "Saint Bernard", Height = 30, Weight = 200, AnimalID = 3 },
new Animal{ Name = "Pug", Height = 12, Weight = 16, AnimalID = 1 },
new Animal{ Name = "Beagle", Height = 15, Weight = 23, AnimalID = 2 }
};
var animalEnum = animalList.OfType<Animal>();
var selectedAnimal = from animal in animalEnum
where animal.Weight <= 90
orderby animal.Name
select animal;
foreach(var animal in selectedAnimal)
{
Console.WriteLine("{0} weight {1}lbs", animal.Name, animal.Weight);
}
Owner[] owners = new[]
{
new Owner{ Name = "Doug Parks", OwnerID = 1 },
new Owner{ Name = "Sally Smith", OwnerID = 2 },
new Owner{ Name = "Paul Brooks", OwnerID = 3 }
};
var nameHeight = from a in animalList
select new
{
a.Name,
a.Height
};
Array arrNameHeight = nameHeight.ToArray();
foreach (var i in arrNameHeight)
{
Console.WriteLine(i.ToString());
}Join
1
2
3
4
5
6
7
8
9
10
11var innerJoin =
from animal in animalList
join owner in owners on animal.AnimalID
equals owner.OwnerID
select new { OwnerName = owner.Name, AnimalName = animal.Name };
foreach (var i in innerJoin)
{
Console.WriteLine("{0} owns {1}",
i.OwnerName, i.AnimalName);
}复杂查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23var groupJoin = from owner in owners
orderby owner.OwnerID
join animal in animalList on owner.OwnerID
equals animal.AnimalID into ownerGroup
select new
{
Owner = owner.Name,
Animals = from owner2 in ownerGroup
orderby owner2.Name
select owner2
};
int totalAnimals = 0;
foreach (var ownerGroup in groupJoin)
{
Console.WriteLine(ownerGroup.Owner);
foreach (var animal in ownerGroup.Animals)
{
totalAnimals++;
Console.WriteLine("* {0}", animal.Name);
}
}
15 - Threads
线程的基本使用方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18static void Print1()
{
for(int i = 0; i < 1000; i++)
{
Console.Write(1);
}
}
static void Main(string[] args)
{
Thread thread = new Thread(Print1);
thread.Start();
for(int i = 0; i < 1000; i++)
{
Console.Write(0);
}
}sleep
1
2
3
4
5
6
7
8int num = 1;
for (int i = 0; i < 10; i++)
{
Console.WriteLine(num);
Thread.Sleep(1000);
num++;
}
Console.WriteLine("Thread Ends");锁的使用
类:
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
35internal class BankAcct
{
private Object acctLock = new Object();
public double Balance { get; set; }
public string Name { get; set; }
public BankAcct(double balance)
{
Balance = balance;
}
public double Withdraw(double amount)
{
if(Balance - amount < 0)
{
Console.WriteLine($"Sorry ${Balance} in Account");
return Balance;
}
lock(acctLock)
{
if(Balance >= amount)
{
Console.WriteLine("Remove {0} and {1} left in account", amount, (Balance - amount));
Balance -= amount;
}
return Balance;
}
}
public void IssueWithdraw()
{
Withdraw(1);
}
}用例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21BankAcct acct = new BankAcct(10);
Thread[] threads = new Thread[15];
Thread.CurrentThread.Name = "main";
for(int i = 0; i < 15; i++)
{
Thread thread = new Thread(new ThreadStart(acct.IssueWithdraw));
thread.Name = i.ToString();
threads[i] = thread;
}
for (int i = 0; i < 15; i++)
{
Console.WriteLine("Thread {0} Alive : {1} ", threads[i].Name, threads[i].IsAlive);
threads[i].Start();
Console.WriteLine("Thread {0} Alive : {1} ", threads[i].Name, threads[i].IsAlive);
}
Console.WriteLine("Current Priority {0}", Thread.CurrentThread.Priority);
Console.WriteLine("Thread {0} Ending", Thread.CurrentThread.Name);其他调用方法
1
2
3
4
5
6
7
8Thread thread = new Thread(() => CountTo(10));
thread.Start();
new Thread(() =>
{
CountTo(5);
CountTo(6);
}).Start();
17 - File I/O
Directory Functions
文件类用法:
包括识别文件信息、创建以及删除文件
1 | DirectoryInfo currentDir = new DirectoryInfo("."); |
FILE READING & WRITING
文件的读取以及写入:
1 | string[] customers = |
File Streams
使用文件流写入数据:
1 | string textFilePath = @"E:\Code\Course\C#\CSharpTutorial\CSharpData\testfile1.txt"; |
StreamWriter/StreamReader
流读写,推荐使用
1 | string textFilePath = @"E:\Code\Course\C#\CSharpTutorial\CSharpData\testfile1.txt"; |
BinaryWriter/BinaryReader
二进制读写器
1 | string textFilePath = @"E:\Code\Course\C#\CSharpTutorial\CSharpData\testfile1.txt"; |
18 - Serialization
可以被序列化的对象需要添加一些功能
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[]
public class Animal : ISerializable
{
public string Name { get; set; }
public double Weight { get; set; }
public double Height { get; set; }
public int AnimalID { get; set; }
public Animal() { }
public Animal(string name, double weight, double height, int id)
{
Name = name;
Weight = weight;
Height = height;
AnimalID = id;
}
public override string ToString()
{
return string.Format("{0} weighs {1} lbs and is {2} inches tall",
Name, Weight, Height);
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
// Assign key value pair for your data
info.AddValue("Name", Name);
info.AddValue("Weight", Weight);
info.AddValue("Height", Height);
info.AddValue("AnimalID", AnimalID);
}
public Animal(SerializationInfo info, StreamingContext ctxt)
{
//Get the values from info and assign them to the properties
Name = (string)info.GetValue("Name", typeof(string));
Weight = (double)info.GetValue("Weight", typeof(double));
Height = (double)info.GetValue("Height", typeof(double));
AnimalID = (int)info.GetValue("AnimalID", typeof(int));
}
}使用序列化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15Animal bowser = new Animal("Bowser", 45, 25, 1);
Stream stream = File.Open("AnimalData.dat", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(stream, bowser);
stream.Close();
bowser = null;
stream = File.Open("AnimalData.dat", FileMode.Open);
bf = new BinaryFormatter();
bowser = (Animal)bf.Deserialize(stream);
stream.Close();
Console.WriteLine(bowser.ToString());
XMLSerialization
单个对象的读写:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19DirectoryInfo dataDir = new DirectoryInfo(@"E:\Code\Course\C#\CSharpTutorial\CSharpData");
if(!dataDir.Exists)
dataDir.Create();
Animal bowser = new Animal("Bowser", 45, 25, 1);
XmlSerializer serializer = new XmlSerializer(typeof(Animal));
using (TextWriter writer = new StreamWriter(@"E:\Code\Course\C#\CSharpTutorial\CSharpData\bowser.xml"))
{
serializer.Serialize(writer, bowser);
}
bowser = null;
XmlSerializer deserializer = new XmlSerializer(typeof(Animal));
TextReader reader = new StreamReader(@"E:\Code\Course\C#\CSharpTutorial\CSharpData\bowser.xml");
object obj = deserializer.Deserialize(reader);
bowser = (Animal)obj;
reader.Close();
Console.WriteLine(bowser.ToString());列表读写:
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
32DirectoryInfo dataDir = new DirectoryInfo(@"E:\Code\Course\C#\CSharpTutorial\CSharpData");
if (!dataDir.Exists)
dataDir.Create();
//Write List
List<Animal> theAnimals = new List<Animal>
{
new Animal("Mario", 60, 30, 2),
new Animal("Luigi", 55, 24, 3),
new Animal("Peach", 40, 20, 4)
};
using (Stream fs = new FileStream(@"E:\Code\Course\C#\CSharpTutorial\CSharpData\bowser.xml", FileMode.Create, FileAccess.Write, FileShare.None))
{
XmlSerializer serializer2 = new XmlSerializer(typeof(List<Animal>));
serializer2.Serialize(fs, theAnimals);
}
theAnimals = null;
XmlSerializer serializer3 = new XmlSerializer(typeof(List<Animal>));
using (FileStream fs2 = File.OpenRead(@"E:\Code\Course\C#\CSharpTutorial\CSharpData\bowser.xml"))
{
theAnimals = (List<Animal>)serializer3.Deserialize(fs2);
}
foreach (Animal a in theAnimals)
{
Console.WriteLine(a.ToString());
}