发送Http异步请求
请求步骤
-
创建 HttpClient 实例
HttpClient client = new HttpClient();
-
发送 HTTP 请求
使用
GetAsync
方法发送了一个 HTTP GET 请求到苹果公司官网的 URL:http://www.apple.com/
。
HttpResponseMessage response= await client.GetAsync("http://www.apple.com/");
-
处理 HTTP 响应
接下来,你可以根据需要处理从服务器返回的 HTTP 响应。在这个例子中,响应被存储在名为
response
的HttpResponseMessage
对象中。
Console.WriteLine("Apple's home page has {0:N0} bytes."
, response.Content.Headers.ContentLength);
这里的N0代表的意思是ContentLength将每隔3位数字添加一个
,
提高可读性,其中N
格式说明符代表“数值(Number)”格式,它自动包括千位分隔符,N
后面的数字表示要显示的小数位数。N0
表示没有小数位。
完整样例代码
HttpClient client =new();
HttpResponseMessage response= await client.GetAsync("http://www.apple.com/");
Console.WriteLine("Apple's home page has {0:N0} bytes."
, response.Content.Headers.ContentLength);
样例代码输出
Apple's home page has 186,743 bytes.
在C#文件中输出编译器和语言的版本
输出编译器版本
string compilerVersion = typeof(object).Assembly.ImageRuntimeVersion;
Console.WriteLine("C# Compiler Version: " + compilerVersion);
输出语言(SDK)版本
string languageVersion = Environment.Version.ToString();
Console.WriteLine("Language Version: " + languageVersion);
一元算术运算符
一元算术运算符是只需要一个操作数的运算符。在C#中,一元运算符有自增(
++
)和自减(--
)。这些运算符通常用于变量的值增加或减少1。有两种类型的自增运算符:前缀(++var
)和后缀(var++
)。前缀版本先执行运算再返回值,而后缀版本先返回值再执行运算。
测试代码
int c = 3;
int d = ++c; // 先自增后赋值
WriteLine($"c is {c}, d is {d}");
预期输出
c is 4, d is 4
二元算术运算符
二元算术运算符包括加 (
+
), 减 (-
), 乘 (*
), 除 (/
), 和求余 (%
)。这些运算符用于执行常见的数学运算。
测试代码:二元算术运算符
int e = 11;
int f = 3;
Console.WriteLine($"e is {e}, f is {f}");
Console.WriteLine($"e + f = {e + f}");
Console.WriteLine($"e - f = {e - f}");
Console.WriteLine($"e * f = {e * f}");
Console.WriteLine($"e / f = {e / f}");
Console.WriteLine($"e % f = {e % f}");
double g = 11.0;
Console.WriteLine($"g is {g:N1}, f is {f}");
Console.WriteLine($"g / f = {g / f}");
测试代码输出结果
e is 11, f is 3
e + f = 14
e - f = 8
e * f = 33
e / f = 3
e % f = 2
g is 11.0, f is 3
g / f = 3.66666666666667
条件逻辑运算符
条件逻辑运算符包括
&
(逻辑与) 和&&
(短路逻辑与)。这些运算符通常用于在条件语句中组合多个条件。&
会检查所有条件,而&&
在遇到第一个false
值时停止计算,实现短路。这里我要特别说明一下:当操作整数值时,&和|符号是按位运算符,而当操作布尔值(如true和false)时,&和|符号是逻辑运算符
测试代码:条件逻辑运算符
bool a = true;
bool b = false;
static bool DoStuff() {
Console.WriteLine("I am doing some stuff.");
return true;
}
Console.WriteLine();
Console.WriteLine($"a & DoStuff() = {a & DoStuff()}");
Console.WriteLine($"b & DoStuff() = {b & DoStuff()}");
Console.WriteLine("------------------------------------------------------");
Console.WriteLine();
Console.WriteLine($"a && DoStuff() = {a && DoStuff()}");
Console.WriteLine($"b && DoStuff() = {b && DoStuff()}");
测试代码输出结果
I am doing some stuff.
a & DoStuff() = True
I am doing some stuff.
b & DoStuff() = False
------------------------------------------------------
I am doing some stuff.
a && DoStuff() = True
b && DoStuff() = False
位运算符
位运算符包括
&
(AND),|
(OR),^
(XOR),<<
(左移)和>>
(右移)。这些操作符主要用于直接对整数的二进制位进行操作。
测试代码:位运算符
int a = 10; // 二进制表示: 00001010
int b = 6; // 二进制表示: 00000110
Console.WriteLine($"a = {a}");
Console.WriteLine($"b = {b}");
Console.WriteLine($"a & b = {a & b}"); // 二进制的AND运算
Console.WriteLine($"a | b = {a | b}"); // 二进制的OR运算
Console.WriteLine($"a ^ b = {a ^ b}"); // 二进制的XOR运算
// 二进制移位运算符
Console.WriteLine($"a << 3 = {a << 3}"); // 将a左移3位
Console.WriteLine($"b >> 1 = {b >> 1}"); // 将b右移1位
// 将整数值转换为包含0和1的二进制字符串
Console.WriteLine();
Console.WriteLine("Outputting integers as binary:");
Console.WriteLine($"a= {ToBinaryString(a)}");
Console.WriteLine($"b= {ToBinaryString(b)}");
static string ToBinaryString(int value)
{
return Convert.ToString(value, 2).PadLeft(8, '0');
}
Convert.ToString(value, toBase:2): 这是 .NET Framework 提供的 Convert 类中的一个方法,
用于将数字转换成其等效的字符串表示形式。value 是要转换的整数,而 toBase:2 指定了基数(二进制)
,因此这个调用将 value 转换为二进制的字符串形式。.PadLeft(8, '0'):
这是字符串的一个方法,用于确保字符串达到一定的长度。如果字符串的长度小于指定的长度(这里是8),
这个方法会在字符串的左边填充指定的字符(这里是 '0')直到字符串的长度为8。
如果字符串长度已经是8或更长,那么这个方法不会改变字符串。
测试代码输出结果
a = 10
b = 6
a & b = 2
a | b = 14
a ^ b = 12
a << 3 = 80
b >> 1 = 3
Outputting integers as binary:
a= 00001010
b= 00000110
整型转换为字符串并提取字符
测试代码:整型转换为字符串并提取字符
int age = 50;
char firstDigit = age.ToString()[0]; // 将整型数据转换成字符串,然后取第一个字符
Console.WriteLine(firstDigit);
测试代码输出结果
5
模式匹配
模式匹配的定义:模式匹配是一种在编程语言中对数据结构进行检查和分解的技术。它允许开发者直接在代码中查询数据的结构,并基于这些数据的形状或属性进行条件操作。模式匹配通常与
switch
语句和条件表达式配合使用,以便更简洁、直观和安全地处理复杂的数据逻辑。在 C# 中,模式匹配被引入在 C# 7.0 版本中,并在后续版本中得到了增强。C# 的模式匹配允许开发者以一种非常直观的方式来检查和转换类型、检查值,甚至解构复杂对象。
模式匹配的主要用途包括:
-
类型模式:
- 通过将对象与一个类型比较,如果匹配成功,则可将其转换为该类型的变量。例如,
if (obj is string s)
会检查obj
是否是string
类型,如果是,则在if
语句的范围内可以作为string
类型的变量s
使用。
- 通过将对象与一个类型比较,如果匹配成功,则可将其转换为该类型的变量。例如,
-
常量模式:
- 检查一个值是否等于某个特定的常量。例如,
case 1:
在switch
语句中就是常量模式的一个例子。
- 检查一个值是否等于某个特定的常量。例如,
-
声明模式:
- 连接类型模式和变量声明,允许不仅检查类型还可以将对象转换为该类型的局部变量。例如,
case int n:
会检查某个值是否为int
类型,并将其存储在变量n
中。
- 连接类型模式和变量声明,允许不仅检查类型还可以将对象转换为该类型的局部变量。例如,
-
位置模式(适用于元组和其他数据结构):
- 解构复杂数据结构,如元组或带有多个属性的对象。例如,在 C# 8.0 中,可以使用
(int x, int y) t
来解构一个元组,并单独检查x
和y
。
- 解构复杂数据结构,如元组或带有多个属性的对象。例如,在 C# 8.0 中,可以使用
-
递归模式:
- 对复杂的数据结构进行更深层次的匹配和解构。C# 9.0 增加了对这种模式的支持,允许在嵌套数据结构中进行匹配。
模式匹配和 if
语句
C# 中的模式匹配允许开发者直接在
if
或switch
语句中进行类型检查和转换。这增加了代码的清晰度和类型安全性。当使用
is
关键字进行类型检查时,如果对象符合指定的类型,可以直接将其转换并赋值给新的变量。在C#中,is
类型模式检查不仅检查对象是否为指定的类型,还可以在同一个语句中将对象转换为那个类型的变量。比如当我用object 定义一个变量的时候,我们可以在if 中使用模式匹配来确保其是我们指定的类型:
object o = "3";
int j=20;
if(o is int i)
{
WriteLine($"{i} x {j} = {i*j}");
}
此时如果o是int类型的话,其就会进入if语句,且将o变量的值赋值给i。
测试代码
object o = "3";
int j = 4;
if (o is int i)
{
Console.WriteLine($"{i} x {j} = {i * j}");
}
else
{
Console.WriteLine("o is not an int so it cannot multiply!");
}
测试代码输出结果
o is not an int so it cannot multiply!
模式匹配和 switch
语句
重点锁定
switch(animal) // animal是一个类
{
case Cat fourLeggedCat when fourLeggedCat.Legs==4:
message = $"The cat named {fourLeggedCat.Name} has four legs.";
break:
}
这里的
case Cat fourLeggedCat when fourLeggedCat.Legs==4:
其实就是模式匹配,执行的时候整个程序发生的步骤顺序如下:
-
类型检查:首先检查
animal
是否可以被视为Cat
类型。这意味着在运行时,animal
的实际类型是否是Cat
或者Cat
的子类。 -
变量赋值:如果
animal
是Cat
类型,那么这个Cat
对象会被赋值给新的局部变量fourLeggedCat
。这个变量仅在这个case
代码块内有效。 -
条件判断:在
when
子句中,它进一步检查fourLeggedCat
的Legs
属性是否等于 4。只有当这个条件也为真时,这个case
代码块才会执行。
完整测试代码
Animals类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SelectionStatements
{
public class Animal
{
public string? Name;
public DateTime Born;
public byte Legs;
}
class Cat :Animal//Cat继承Animal类
{
public bool IsDomestic;
}
class Spider : Animal//Spider继承Animal类
{
public bool IsPoisonous;
}
}
主代码Program.cs
Animal?[] animals=new Animal?[]
{
new Cat{Name="Karen",Born=new(year:2022,month:8,day:23),
Legs=4,IsDomestic=true
},
null,
new Cat{Name="Mufasa",Born=new(year:1994,month:6,day:12)},
new Spider{Name="Sid Vicious",Born=DateTime.Today, IsPoisonous=true},
new Spider{Name = "Captain Furry",Born=DateTime.Today}
};
foreach(Animal? animal in animals)
{
string message;
switch(animal)
{
case Cat fourLeggedCat when fourLeggedCat.Legs==4:
message = $"The cat named {fourLeggedCat.Name} has four legs.";
break;
case Cat wildCat when wildCat.IsDomestic ==false:
message=$"The non-domestic cat is named {wildCat.Name}.";
break;
case Cat cat:
message=$"The cat is named {cat.Name}.";
break;
default:
message=$"The animal named {animal.Name} is a {animal.GetType().Name}.";
break;
case Spider spider when spider.IsPoisonous:
message=$"The {spider.Name} spider is poisonous. Run!";
break;
case null:
message="The animal is null.";
break;
}
WriteLine($"switch statement: {message}");
}
测试代码输出:
switch statement: The cat named Karen has four legs.
switch statement: The animal is null.
switch statement: The non-domestic cat is named Mufasa.
switch statement: The Sid Vicious spider is poisonous. Run!
switch statement: The animal named Captain Furry is a Spider.
标签和 goto
语句的用法
标签
标签是程序中的一个点,你可以在代码的任何地方定义一个标签,并通过
goto
语句跳转到它。标签作为目的地,需要给出一个唯一的标识符。在switch
语句中,标签常用于在不同的case
之间进行跳转。
标签的格式
labelName:
{
}
其中这个labelName可以取任何你喜欢的名字。说白了就是一个名字外加一个冒号就叫标签了,
{}
则是限定标签的范围。
示例代码:使用标签
int step = 1;
start:
if (step == 1)
{
Console.WriteLine("Step 1 executed");
step = 2;
goto start; // 跳转到 start 标签
}
else
{
Console.WriteLine("Final step executed");
}
示例输出:使用标签
Step 1 executed
Final step executed
这里要进行说明一下,标签其实和函数和方法那些都不一样,它其实最大的作用就是限定了一片范围,便于goto调用,比如我在某个地方我突然想要调用几行我曾经用过的代码,那我们就可以用标签去限定范围,具体限定代码范围我们可以在标签符号
:
加{}
即可,最后我们直接goto调用标签即可。
goto
语句
goto
语句用于无条件地跳转到同一代码块中的一个标签。在switch
语句中,goto
可以用来实现从一个case
跳转到另一个case
或跳到switch
外部的标签。
示例代码:使用 goto
在 switch
语句中
int number = 2;
switch (number)
{
case 1:
Console.WriteLine("One");
break;
case 2:
Console.WriteLine("Two");
goto case 1; // 跳转到 case 1
case 3:
Console.WriteLine("Three");
break;
default:
Console.WriteLine("Something else");
break;
}
示例输出:使用 goto
在 switch
语句中
Two
One
停留在世界边缘,与之惜别