【To .NET】C#基础较难易混知识点整理

大家好!我是未来村村长,就是那个“请你跟我这样做,我就跟你这样做!”的村长👨‍🌾!

👩‍🌾“人生苦短,你用Python”,“Java内卷,我用C#”。

​ 从Java到C#,不仅仅是语言使用的改变,更是我从理想到现实,从象牙塔到大熔炉的第一步。.NET是微软的一盘棋,而C#是我的棋子,只希望微软能下好这盘棋,而我能好好利用这个棋子。

一、编程基础篇

1、空值处理

​ 如下代码会报错:CS0037-无法将 null 转换为“int”,因为后者是不可为 null 的值类型。

int nullProp = null;
Console.WriteLine($"nullProp = {nullProp}");

​ 因为像int和DateTime这样的值类型必须总是有值的。像string这样的引用类型可以为空。

string nullProp = null;
Console.WriteLine($"nullProp = {nullProp}");

​ 一般情况下不允许变量有空值,可以通过设置项目级选项来启用该特性。

​ 项目级别:

<PropertyGroup>
    <Nullable>enable</Nullable>
</PropertyGroup>

​ 文件级启用与禁用:

# nullable enable
# nullable disable

​ 当我们启用了可空引用类型,并希望为引用类型分配空值,我们需要在类型声明后添加?。

​ ?.则是用于检查变量是否为空,是if(不为空)的语法糖。

# nullable enable
using System;

namespace fineyun
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string? nullProp = null;
            string? notNullProp = null;
            Console.WriteLine($"nullProp = {notNullProp?.Length}");
        }
    }
}

二、控制程序流和转换类型

1、条件逻辑运算符与逻辑运算符

​ &&是条件逻辑运算符中的"并且",其会先判断左操作数是否为true,若为false则结束语句不执行右操作数的执行。我们可以用该特点写较为简洁高效的代码。除此条件逻辑运算符还有||。

bool DoNotDo = false;
DoNotDo && Do();

​ 而逻辑运算符对布尔值进行操作,有|表示或,&表示且,^表示异或,不同为true,相同则为false,还有!表示非。

2、圆整规则

C#中进行浮点数向int类型强制转换时,圆整规则如下:

  • 小数部分小于0.5,向下取整
  • 小数部分大于0.5,向上取整
  • 小数部分等于0.5,奇数向上取整,偶数向下取整

3、字符串的转换

​ 字符串转换为数字或日期和时间,可以使用相应类型的Parse方法。

int i = int.Parse("1");
DateTime today = DateTime.Parse(4 july 2022);

​ 一般使用Try Parse避免异常,out代表赋值输出的变量,方法返回bool类型。除此还可以使用System.Convert方法进行转换。

int i;
int.TryParse("哈哈哈",out i);

4、捕获异常

​ 要获取可能发生的任何异常信息,可以catch类型为Exception的变量,捕获特定异常则catch相应的异常类型。

catch(Exception ex){
    WriteLine($"{ex.Message}")
}

5、检查溢出

​ checked语句告诉.NET。要在发生溢出时抛出异常,而不是沉默不语。因为发生溢出时,会出现取值异常,不会进行报错。

checked{
    int x = int.MaxValue - 1;
}

​ 我们可以通过catch OverflowException异常进行相应的处理。

三、面向对象

​ 在C#中,可使用C#关键字class(通常)或struct(偶尔)来定义对象的类型。封装是对象相关的数据和操作的集合,组合是指物体由什么构成,聚合指什么可以与对象相结合,继承是指从基类或超类派生子类来实现重用,抽象是提取对象的核心。

1、类的成员

​ C#中类的成员十分不同于Java,Java中类的成员无非变量(属性)和方法。C#中的成员可分为两类:字段和方法。

​ 其中字段:

  • 常量字段:const修饰的字段
  • 只读字段:readonly修饰的字段
  • 事件:数据引用一个或多个方法,方法在发生事件时执行

​ 其中方法:

  • 构造函数:使用new关键字分配内存和实例化类时执行的语句
  • 属性:获取或设置数据时执行的语句
  • 索引器:使用数组语法[]获取或设置数据时执行的语句
  • 运算符:对类型的操作数使用+和/之类的运算符执行的语句

2、元组

​ 元组类型方法:

public (string,int) GetKeyValue(){
    return ("key",1);
}

​ 元组类型:

(string,int) keyValue = GetKeyValue();

3、参数的定义

(1)可选参数

​ 除了重载方法以外,我们还可以通过可选参数的方式简化方法。通过在方法的参数列表中指定默认值,可以使参数成为可选。

public string OptionalParamenters(string name = "未来村村长",
                                 int id = 0,
                                 bool isHandsome = ture){
    return $"{name}{id}{isHandsome}"
}

OptrionalParamenters("未来村村民",2);//name和id会改变,isHandsome不会改变

​ 还可以通过使用命名参数改变传参的顺序。

OptrionalParamenters(id:2,name:"未来村村民");
(2)控制参数的传递方式

​ 但传递参数给方法时,参数可以通过三种方式进行传递:

  • 值:传入变量的副本,方法不能对变量进行修改
  • ref引用:传入变量的引用,方法会对变量进行修改
  • 作为out参数:传入的变量会被方法中的out 参数替换

4、Partial关键字

​ 关键字partial是一个上下文关键字,其作用是将一个类(或class、struct、interface)分解到不同的类文件中,在最终编译时可将其合并。局部类型的各个部分一般是分开放在几个不同的.cs文件中,但C#编译器允许我们将他们放在同一文件中.

局部类型上的修饰符:

  • 一个类型的各个部分上的访问修饰符必须维持一致性

  • 如果一个类型有一个部分使用了abstract修饰符,那么整个类都将被视为抽象类

  • 如果一个类型有一个部分使用了 sealed 修饰符,那么整个类都将被视为密封类

  • 一个类的各个部分不能使用相互矛盾的修饰符,比如abstract和sealed

局部类型的基类和接口:

​ 一个类型的各个部分上指定的基类必须一致。某个部分可以不指定基类,但如果指定,则必须相同
局部类型上的接口具有“累加”效应。

5、属性

​ Java中将变量和方法分离,并建议通过编写getter和setter方法来进行变量的访问和设置。而在C#中使用属性来完成该工作。

public string prop{get; set;}
//只读属性
public string prop{get;}

6、索引器

​ 索引器允许调用代码使用数组语法来访问属性,字符串类型就定义了索引器,这样通过[]就可以访问字符串中的字符。

​ 我们来看ArrayList中的索引器:

public virtual Object this[int index] {
            get {
                if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
                Contract.EndContractBlock();
                return _items[index];
            }
            set {
                if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
                Contract.EndContractBlock();
                _items[index] = value;
                _version++;
            }
}

​ 一般的索引器格式为:

public 返回类型 this[int index]{
    get{
        return item[index];//item为该类的数组属性
    }
    set{
        item[index] = value;
    }
}

四、接口和继承

1、局部函数

​ C#7.0开始,可以在函数中定义局部函数。

public int c(){
    retrun F();
    int F(){
        return 0;
    }
}

2、委托和事件

​ 方法是对象可以执行的操作,事件是发生在对象上的操作,事件建立于委托。

(1)委托

​ 委托是调用方法的另一种方式,委托为方法的调用提供了灵活性,还能用于多线程允许多个操作并行执行。

在C#中使用委托具体步骤如下:

  • 声明一个委托,其参数形式一定要和想要包含的方法的参数形式一致,返回值也需要一致;

  • 创建委托对象并将所希望的方法包含在该委托对象中;

  • 通过委托对象调用包含在其中的各个方法;

  • 可通过+,+=,-,-=对代理对象进行组合执行。

//声明一个委托
delegate int MyDelegate();
//定义需要被代理的类
class Myclass{
    //定义被代理方法
    public int M1(){
        return 0;
    }
    public static int M2(){
        return 0;
    }
}
//Main类
class Test{
    static void Main(){
        //定义被代理对象
        Myclass w = new MyClass();
        //实例化代理对象,传入相关方法
        MyDelegate p = new MyDelegate(w.M1);
        p();//通过代理对象(),进行代理方法的执行
        //可直接代理静态方法
        MyDelegate b = new MyDelegate(Mycalss.M2);
        b();
        //可通过+,+=,-,-=对代理对象进行组合执行
        Mydelegate g = p + b;
        g()
        
    }
}

​ 微软定义了两个预定义的委托可用于事件。

public delegate void EventHandler(object sender,EventArgs e);
public delegate void EventHandler<TEventArgs>(object sender,TEventArgs e);
(2)事件

​ 事件的创建与执行流程可分为:事件的声明、事件的预定和取消、事件的发生。

​ 事件的声明:

[修饰符] event 委托名 事件名;

​ 事件的预定和取消:

事件名 += new 委托名(方法名);
事件名 -= new 委托名(方法名);
事件的发生:
事件名(参数);

3、内存的分配

​ 内存有两种:堆内存和栈内存,在现代操作系统,栈和堆可以位于物理或虚拟内存中的任意位置。

​ 使用class定义类型时,是在定义引用类型。这意味着用于对象本身的内存是在堆上分配的,只有对象的内存地址存储在栈上。

​ 使用struct定义类型时,是在定义值类型,意味着用于对象本身的内存是在栈上分配的。

4、成员的隐藏和覆盖

​ 子类继承超类时,若在子类中重写了与超类同名的方法或者属性,不会报错但会发出覆盖警告,我们可以在方法返回参数类型前加上new表示我们是故意为之。

​ 与其隐藏方法,不如直接覆盖。我们可以在基类中通过virtual关键字来重写方法,然后在子类中通过override来进行方法的覆盖。

​ 若方法不希望被继承或覆盖,我们可以使用sealed关键字来防止别人继承自己的类。

5、构造函数与继承

​ 与普通的方法不同,构造函数不是继承的,必须显式地声明和调用System.Exception中的base构造函数实现。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未来村村长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值