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;

12.析构元组

C# 提供内置的元组析构支持,可在单个操作中解包一个元组中的所有项。 用于析构元组的常规语法与用于定义元组的语法相似:将要向其分配元素的变量放在赋值语句左侧的括号中。

// 语句将四元组的元素分配给 4 个单独的变量:
var (name, address, city, zip) = contact.GetAddressInfo();
// 显示声明每个字段的类型
(string city, int population, double area) = QueryCityData("New York City");
// var 关键字单独与任一或全部变量声明结合使用。
(string city, var population, var area) = QueryCityData("New York City");
// 可在析构中混合使用变量声明和赋值。
string city = "Raleigh";
int population = 458880;
(city, population, double area) = QueryCityData("New York City");

12.1 弃元的析构元组

析构元组可以将不必要输出的元素,用弃元来代替

var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010);

13.异常

13.1 异常的执行流程

  1. 引发异常后,运行时将检查当前语句,以确定它是否在 try 块内。 如果在,则将检查与 try 块关联的所有 catch 块,以确定它们是否可以捕获该异常。 Catch 块通常会指定异常类型;如果该 catch 块的类型与异常或异常的基类的类型相同,则该 catch 块可处理该方法。
  2. 如果引发异常的语句不在 try 块内或者包含该语句的 try 块没有匹配的 catch 块,则运行时将检查调用方法中是否有 try 语句和 catch 块。 运行时将继续调用堆栈,搜索兼容的 catch 块。 在找到并执行 catch 块之后,控制权将传递给 catch 块之后的下一个语句。
  3. 一个 try 语句可包含多个 catch 块。 将执行第一个能够处理该异常的 catch 语句;将忽略任何后续的 catch 语句,即使它们是兼容的也是如此。 按从最具有针对性(或派生程度最高)到最不具有针对性的顺序对 catch 块排列。
  4. 执行 catch块之前,运行时会检查 finally 块。 Finally 块使程序员可以清除中止的 try 块可能遗留下的任何模糊状态,或者释放任何外部资源(例如图形句柄、数据库连接或文件流),而无需等待垃圾回收器在运行时完成这些对象。

13.2 异常处理try catch finally

try
{
     // Code to try goes here.
}
catch (SomeSpecificException ex)
{
    // Code to handle the exception goes here.
}
finally
{
    // Code to execute after the try (and possibly catch) blocks
    // goes here.
}

14.命令约定

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

  • 属性类型以单词 Attribute 结尾。

  • 枚举类型对非标记使用单数名词,对标记使用复数名词。

  • 标识符不应包含两个连续的下划线 (_) 字符。 这些名称保留给编译器生成的标识符。

  • 命名 classrecordstruct 时,使用 pascal 大小写(“PascalCasing”)。

  • 命名类型的 public 成员(例如字段、属性、事件、方法、函数中的参数和本地函数)时,请使用 pascal 大小写。

  • public bool IsValid;
    public record PhysicalAddress(
        string Street,
        string City,
        string StateOrProvince,
        string ZipCode);
    
  • 命名 privateinternal 字段时,使用驼峰式大小写(“camelCasing”),并且它们以 _ 作为前缀。

  • private IWorkerQueue _workerQueue;
    
  • 使用为 privateinternalstatic 字段时 请使用 s_ 前缀,对于线程静态,请使用 t_

  • private static IWorkerQueue s_workerQueue;
    [ThreadStatic]
    private static TimeSpan t_timeSpan;
    

15.继承

以下成员无法从基类中继承:

  • 静态构造函数:用于初始化类的静态数据。
  • 实例构造函数:在创建类的新实例时调用。 每个类都必须定义自己的构造函数。
  • 终结器:由运行时的垃圾回收器调用,用于销毁类实例。
// 只有在基类中嵌套的派生类中,私有成员才可见。
public class A
{
    private int _value = 10;

    public class B : A
    {
        public int GetValue()
        {
            return _value;
        }
    }
    // 基类成员必须标记有 virtual 关键字,才能重写继承的成员。
    public virtual void Method(){}
}

public class C : A
{
    //    public int GetValue()
    //    {
    //        return _value;
    //    }
    public override void Method(){}
}



网络必备基础

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习安排:4周4个项目实战 学习形式:录播视频+在线作业考核+助教一对一辅导答疑 1. C#基本语法:基本编程(If:…else)语句、数组等。2. C#面向对象编程:封装、继承、多态性、面向接口编程、动态多态性、字符串基础等。3. .Net 框架原理讲解:多维数组、可变参数 Params、类的实例化内存分配机制等。4. 深入学习对象类型:里氏替换原则(LSP)、类的属性极其本质特性、IS ,AS 关键字、深入学习字符串理论、枚举类型以及适用场合。5. 深入学习集合特性:索引器、自定义集合、深入刨析集合类型本质(ArrayList、HashTable)、学习泛型集合、泛型约束等。6. 学习委托与事件:委托与事件的区别、匿名方法、Lambda表达式。7. 正则表达式。8. 查询表达式Linq。9. 反射、特性、动态编程。10. 多线程编程。11. Socket通讯技术。 第二模块:Unity 入门与基础 学习安排:4周3个项目实战 学习形式:录播视频+在线作业考核+助教一对一辅导答疑 课程内容:游戏与Unity发展历史概述、 3D 模型基础、 地形编辑器、光源、音频、Unity脚本程序基础、GUI、3D模型动画的导入 与基本应用、物理学模拟(初级)、碰撞盒与触发器、协程、SendMessage数据传值技术等。 学习安排:4周4个项目实战 学习形式:录播视频+在线作业考核+助教一对一辅导答疑 课程内容:讲解粒子系统、Mecanim、导航寻路、Unity游戏移植技术、Mecanim 动画系统、导航寻路、项目研发常用优化策略、Unity游戏移植与手指触控识别、射线、数据持久化、对象缓冲池技术、物理学模拟(铰链关节(Hinge Joint)、弹簧关节 、固定关节、角色关节)与资源动态加载技术(AssetBundle与WWW)等。 第四模块:Unity项目实训: ARPG项目"地下守护神" 学习安排:4周1个项目实战 学习形式:录播视频+在线作业考核+助教一对一辅导答疑 课程内容:1:前端分层的MVC架构搭建,开发自定义的资源动态加载插件、音频插件、对话系统插件、事件监听插件等。2: UI粒子特效、场景淡入淡出控制。3: 单机与移动端的双输入控制系统开发。4: 数值平衡处理与开发。5: 多种设计模式在游戏研发过程中的灵活运用。6: XML技术的灵活运用,在系统解耦与资源国际化方面的技术突破。7: 开发强大灵活的日志系统插件,应对服务器与移动端的各种复杂系统调试需求。8:开发“对话系统”,与“新手导航”。9:开发基于XML的对象持久化技术。10:开发“背包系统”、“商城系统”、“公告系统”、“任务系统”。11:开发“副本”多种类怪物的战斗系统。12:开发各种战斗特效系统: “血条”、“漂字”、“连击”等功能。 第五模块:虚拟现实(VR)与增强现实技术(AR) 学习安排:1周2个项目实战 学习形式:录播视频+在线作业考核+助教一对一辅导答疑 课程内容:R虚拟现实技术开发:先从什么是虚拟现实(VR)、虚拟现实的主要特点、虚拟现实技术的基础底层原理、国际与国内的产业布局、国际权威机构未来发展趋势预测等讲起。然后主要介绍国际主要领军品牌:Oculus、HTC、SonyVR等产品规格、主要性能指标等。最后重点以一款国内著名VR产品:3Glasses 为代表,介绍VR产品的具体使用、维护、与开发项目全过程流程等。AR 增强实现开发:讲解什么是增强现实、注册高通AR账号、制作识别图、SDK下载与制作、打包发布

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值