C#的基础知识

1. C#的反射 版本C#10.0

1.1. 可以使用 typeof 关键字或 .GetType() 方法来获取已知类型的 Type 对象。

Type stringType = typeof(string); // 使用 typeof 关键字获取字符串类型的 Type 对象

string str = "Hello, world!";
Type stringType = str.GetType(); // 使用 GetType() 方法获取 str 对象的类型 Type 对象

1.2. 反射机制获取属性

以下是获取属性信息的基本步骤:

  1. 使用 typeof 方法或 .GetType() 方法获取所需类型的 Type 对象。
  2. 使用 Type 类中的 GetProperty 方法获取该类型的指定属性。该方法需要传入一个参数,指定要获取的属性的名称。GetProperties() 获取属性列表数组。
  3. 获取返回的 PropertyInfo 对象即可获得属性的相关信息,例如其名称、类型、访问修饰符等。
Type myClassType = typeof(MyClass);   // 获取 MyClass 类型
PropertyInfo propertyInfo = myClassType.GetProperty("Name");    // 获取 Name 属性

Console.WriteLine($"属性名称:{propertyInfo.Name}");
Console.WriteLine($"属性类型:{propertyInfo.PropertyType}");
Console.WriteLine($"Get 访问器可见性:{propertyInfo.GetMethod.IsPublic}");
Console.WriteLine($"Set 访问器可见性:{propertyInfo.SetMethod.IsPublic}");

1.3. 反射机制获取方法

以下是获取方法信息的基本步骤:

  1. 使用 typeof 方法或 .GetType() 方法获取所需类型的 Type 对象。
  2. 使用 Type 类中的 GetMethod 方法获取该类型的指定方法。该方法需要传入一个参数,指定要获取的方法的名称。
  3. 获取返回的 MethodInfo 对象即可获得方法的相关信息,例如其名称、返回类型、访问修饰符等。

2. 字符串内插

通过定义表达式(其结果放置在格式字符串中)来设置字符串格式。内插字符串通过 $ 标记来声明。 字符串插内插计算 {} 之间的表达式,然后将结果转换为 string,并将括号内的文本替换为表达式的字符串结果。

Console.WriteLine($"The low and high temperature on {weatherData.Date:MM-dd-yyyy}");
Console.WriteLine($"    was {weatherData.LowTemp} and {weatherData.HighTemp}.");
// Output (similar to):
// The low and high temperature on 08-11-2020
//     was 5 and 30.

3. 空值类型

任何可为空的值类型都是泛型 System.Nullable 结构的实例。

3.1 声明和赋值

int?[] arr = new int?[10];
bool? flag = null;

3.2 检查值是否为空

3.2.1 is 既检查 null 的可为空值类型的实例,又检索基础类型的值:
int? a = 42;
if (a is int valueOfA)
{
    Console.WriteLine($"a is {valueOfA}");
}
else
{
    Console.WriteLine("a does not have a value");
}
// Output:
// a is 42
3.2.2 HasValue 属性检查空值
int? b = 10;
if (b.HasValue)
{
    Console.WriteLine($"b is {b.Value}");
}
else
{
    Console.WriteLine("b does not have a value");
}
// Output:
// b is 10

3.3 将空值类型转化为基础数据类型

使用 Null 合并操作符??,将可为空值类型的值分配给不可以为 null 的值类型变量,则可能需要指定要分配的替代 null 的值。

int? a = 28;
int b = a ?? -1;
Console.WriteLine($"b is {b}");  // output: b is 28

int? c = null;
int d = c ?? -1;
Console.WriteLine($"d is {d}");  // output: d is -1

3.4 空值类型的比较

对于比较运算符<><=>=,如果一个或全部两个操作数都为 null,则结果为 false;null == null 为true。

4.required 修饰符

required 修饰符使开发人员能够创建必须正确初始化属性或字段的类型,但仍允许使用对象初始值设定项进行初始化。

public class Person
{
    public required string LastName { get; set; }
    public required string FirstName { get; set; }
}

var p1 = new Person(); // Error! Required properties not set
var p2 = new Person() { FirstName = "Grace", LastName = "Hopper" };

5.记录 recode

不可变性值相等性非破坏性变化用于显示的内置格式设置继承

不可变性:将不能更改值型属性的值或引用型属性的引用。

如果不替代或替换相等性方法,则声明的类型将控制如何定义相等性:

  • 对于 class 类型,如果两个对象引用内存中的同一对象,则这两个对象相等。

  • 对于 struct 类型,如果两个对象是相同的类型并且存储相同的值,则这两个对象相等。

  • 对于具有 record 修饰符(record classrecord structreadonly record struct)的类型,如果两个对象是相同的类型并且存储相同的值,则这两个对象相等。

  • public record Person(string FirstName, string LastName, string[] PhoneNumbers);
    
    public static void Main()
    {
        var phoneNumbers = new string[2];
        Person person1 = new("Nancy", "Davolio", phoneNumbers);
        Person person2 = new("Nancy", "Davolio", phoneNumbers);
        Console.WriteLine(person1 == person2); // output: True
    
        person1.PhoneNumbers[0] = "555-1234";
        Console.WriteLine(person1 == person2); // output: True
    
        Console.WriteLine(ReferenceEquals(person1, person2)); // output: False
    }
    

如果需要复制包含一些修改的实例,可以使用 with 表达式来实现非破坏性变化。 with 表达式创建一个新的记录实例,该实例是现有记录实例的一个副本,修改了指定属性和字段。

public record Person(string FirstName, string LastName)
{
    public string[] PhoneNumbers { get; init; }
}

public static void Main()
{
    Person person1 = new("Nancy", "Davolio") { PhoneNumbers = new string[1] };
    Console.WriteLine(person1);
    // output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] }

    Person person2 = person1 with { FirstName = "John" };
    Console.WriteLine(person2);
    // output: Person { FirstName = John, LastName = Davolio, PhoneNumbers = System.String[] }
    Console.WriteLine(person1 == person2); // output: False

    person2 = person1 with { PhoneNumbers = new string[1] };
    Console.WriteLine(person2);
    // output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] }
    Console.WriteLine(person1 == person2); // output: False

    person2 = person1 with { };
    Console.WriteLine(person1 == person2); // output: True
}

6.密封类 sealed

通过在类定义前面放置关键字 sealed,可以将类声明为密封类,可阻止其他类继承自该类。

public sealed class D
{
    // Class members here.
}

7.接口

接口名称以大写字母 I 开头。

7.1 显式接口实现

两个不同的接口调用不同的实现

public interface IControl
{
    void Paint();
}
public interface ISurface
{
    void Paint();
}

public class SampleClass : IControl, ISurface
{
	// 显示接口的调用
    void IControl.Paint()
    {
        System.Console.WriteLine("IControl.Paint");
    }
    void ISurface.Paint()
    {
        System.Console.WriteLine("ISurface.Paint");
    }
}

SampleClass sample = new SampleClass();
IControl control = sample;
ISurface surface = sample;

// The following lines all call the same method.
sample.Paint();
control.Paint();
surface.Paint();

// Output:
// Paint method in SampleClass
// Paint method in SampleClass
// Paint method in SampleClass

8.匿名类型

将一组制度属性封装到单个对象中,无需首先定义一个显式类型。可结合使用 new 运算符和对象初始值设定项创建匿名类型。常用于擦寻表达式的select字句中。

var v = new { Amount = 108, Message = "Hello" };

// Rest the mouse pointer over v.Amount and v.Message in the following
// statement to verify that their inferred types are int and string.
Console.WriteLine(v.Amount + v.Message);

9.模式匹配 switch

相当于switch语法的简写。

9.1 单值比较离散值

可以通过测试变量找到特定值的匹配项。 弃元在Switch中表示默认值。

public State PerformOperation(Operation command) =>
   command switch
   {
       Operation.SystemTest => RunDiagnostics(),
       Operation.Start => StartSystem(),
       Operation.Stop => StopSystem(),
       Operation.Reset => ResetToReady(),
       _ => throw new ArgumentException("Invalid enum value for command", nameof(command)),
   };

具体来说,该代码定义了一个名为 PerformOperation 的公共方法,接受一个参数 command,并返回一个 State 枚举型对象。在方法中,使用 switch 表达式对 command 进行匹配,并针对不同的枚举值执行不同的操作。其中,枚举值 Operation.SystemTest 对应的操作是调用 RunDiagnostics 方法,枚举值 Operation.Start 对应的操作是调用 StartSystem 方法,枚举值 Operation.Stop 对应的操作是调用 StopSystem 方法,枚举值 Operation.Reset 对应的操作是调用 ResetToReady 方法。如果 command 不匹配任何已知的枚举值,则会抛出一个 ArgumentException 异常。

9.2 多值比较

public decimal CalculateDiscount(Order order) =>
    order switch
    {
        { Items: > 10, Cost: > 1000.00m } => 0.10m,
        { Items: > 5, Cost: > 500.00m } => 0.05m,
        { Cost: > 250.00m } => 0.02m,
        null => throw new ArgumentNullException(nameof(order), "Can't calculate discount on null order"),
        var someObject => 0m,
    };

在方法中,使用 switch 表达式对 order 进行模式匹配。在模式匹配中,使用括号表示一个元组,其中包含多个用逗号分隔的子模式。每个子模式都可以包含一个常量、一个变量、关系运算符和逻辑运算符等表达式。在这个例子中,第一个元组子模式 ( > 10, > 1000.00m) 表示当订单中商品数量大于 10,订单总金额大于 1000.00 元时,折扣率为 0.10;第二个元组子模式 ( > 5, > 50.00m) 表示当订单中商品数量大于 5,订单总金额大于 50.00 元时,折扣率为 0.05;第三个子模式 { Cost: > 250.00m } 表示当订单总金额大于 250.00 元时,折扣率为 0.02。如果 order 参数为空,则会抛出一个 ArgumentNullException 异常。最后一个 var someObject => 0m 表示所有其他情况的折扣率都为 0。

10.弃元

弃元指的是一种占位符,用于表示一个不需要使用的变量或返回值。通常,我们可以使用下划线“_”作为弃元的名称。

string firstName, lastName;
(_, lastName) = GetFullName("John Smith");

在这个例子中,方法GetFullName返回两个字符串值,我们使用弃元来忽略第一个值,并将第二个值赋值给了lastName变量。

10.1 对具有 out 参数的方法的调用

调用 DateTime.TryParse(String, out DateTime) 方法来确定日期的字符串表示形式在当前区域性中是否有效。 因为该示例侧重验证日期字符串,而不是解析它来提取日期,所以方法的 out 参数为占位符。

string[] dateStrings = {"05/01/2018 14:57:32.8", "2018-05-01 14:57:32.8",
                      "2018-05-01T14:57:32.8375298-04:00", "5/01/2018",
                      "5/01/2018 14:57:32.80 -07:00",
                      "1 May 2018 2:57:32.8 PM", "16-05-2018 1:00:32 PM",
                      "Fri, 15 May 2018 20:10:57 GMT" };
foreach (string dateString in dateStrings)
{
    if (DateTime.TryParse(dateString, out _))
        Console.WriteLine($"'{dateString}': valid");
    else
        Console.WriteLine($"'{dateString}': invalid");
}
// The example displays output like the following:
//       '05/01/2018 14:57:32.8': valid
//       '2018-05-01 14:57:32.8': valid
//       '2018-05-01T14:57:32.8375298-04:00': valid
//       '5/01/2018': valid
//       '5/01/2018 14:57:32.80 -07:00': valid
//       '1 May 2018 2:57:32.8 PM': valid
//       '16-05-2018 1:00:32 PM': invalid
//       'Fri, 15 May 2018 20:10:57 GMT': invalid

11.lambda 表达式

表达式位于 => 运算符右侧的 lambda 表达式称为“表达式 lambda”。左侧是输入的参数。将此lambda赋值给变量MethodName。

var MethodName = (input-parameters) => expression
    
/*
相当于是一个方法 
private var MethodName(string a){
	expression;
}
*/

11.1 lambda 表达式的输入参数

Func<int, int, bool> testForEquality = (x, y) => x == y;

//表示前两个int 为输入参数类型,后面一个bool为返回值类型。

11.2 异步 lambda

给lambda 表达式加上 asyncawait 关键字。

// 异步lambda
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        button1.Click += async (sender, e) =>
        {
            await ExampleMethodAsync();
            textBox1.Text += "\r\nControl returned to Click event handler.\n";
        };
    }

    private async Task ExampleMethodAsync()
    {
        // The following line simulates a task-returning asynchronous process.
        await Task.Delay(1000);
    }
}

// 原始函数
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        button1.Click += button1_Click;
    }

    private async void button1_Click(object sender, EventArgs e)
    {
        await ExampleMethodAsync();
        textBox1.Text += "\r\nControl returned to Click event handler.\n";
    }

    private async Task ExampleMethodAsync()
    {
        // The following line simulates a task-returning asynchronous process.
        await Task.Delay(1000);
    }
}

11.3 显示返回类型

// 返回的 object类型
var choose = object (bool b) => b ? 1 : "two"; // Func<bool, object>

11.4 给输入参数添加修饰属性

将属性添加到 Lambda 表达式或其参数时,必须将输入参数括起来。

// 表示输入的参数是非空
var concat = ([DisallowNull] string a, [DisallowNull] string b) => a + b;

网络必备基础

1、物理层
2、数据链路层与交换机
3、网络模型 OSI TCP 对等传输
4、虚拟局域网 VLAN
5、静态路由与配置
6、网络地址转换 NAT
7、访问控制列表 ACL
8、IP 协议与 IP 地址分类
9、子网掩码
10、网关
11、子网划分

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值