总结C#学习中的一些基础知识

1 枚举

    enum E_MonsterType//定义了一个枚举的变量类型
        {
            normal1,//0
            boss = 5,//5
            normal2,//6,前一个自动加1
        }
    //枚举和switch语句天生一对,写switch时能对枚举类型自动补全
    E_MonsterType monsterType = E_MonsterType.boss;/声明枚举变量
        switch (monsterType)
        {
            case E_MonsterType.normal1:
                Console.WriteLine("普通怪物逻辑");
                break;
            case E_MonsterType.boss:
                Console.WriteLine("boss怪物逻辑");
                break;
            default:
                break;
        }

2 数组

2.1 数组

    int[] arr1;//声明数组但没有初始化
    int[] arr2 = new int[5];//初始化,不设置初始值则默认为0
    int[] arr3 = new int[5] {1,2,3,4,5};//初始化并赋值,设置的长度是多少,则初始一定要赋多少值
    int[] arr4 = new int[] {1,2};//数组长度看大括号里面有几个就是几个
    int[] arr5 = {1,5,6,7};
    int[] arr6 = new int[8];
    bool[] arr7 = new bool[] { true,false };
 
    Console.WriteLine(arr5.Length);//数组变量名.Length获取数组长度
    foreach(int i in arr5)
    {
        Console.WriteLine(i);
    }
 
    //数组定义之后,是没办法直接添加新的元素,只能通过声明新的数组再复制过去
    for(int i = 0; i < arr5.Length; i++)
    {
        arr6[i] = arr5[i];
    }
    arr6[7] = 8;

2.2 二维数组

    int[,] arr;
    int[,] arr2 = new int[3,3];//初始化一个三行三列全0的二维数组
    int[,] arr3 = new int[3,3] { { 1,3 },{ 4,6 },{ 7,8,9 } };//初始化并定义三行三列的数组
    int[,] arr4 = new int[,] { { 1,9 } };
    int[,] arr5 = { { 1,9 } };
 
    Console.WriteLine(arr5.GetLength(0));//获取二维数组的行数
    Console.WriteLine(arr5.GetLength(1));//获取二维数组的列数
 
    //foreach也可以按行优先原则输出二维数组元素
    foreach(int i in arr5)
    {
        Console.WriteLine("{0}",i);
    }

2.3 交错数组

    int[][] arr1 = new int[3][] { new int[] { 1,new int[] { 4,5 },new int[] { 6 } };//每行的列数可以不同
    Console.WriteLine($"数组的行数为:{arr1.GetLength(0)}");
    Console.WriteLine($"数组某一行的列数为:{arr1[0].Length}");
    foreach (int[] a in arr1)//交错数组的元素是数组
    {
        foreach(int b in a)
        {
            Console.WriteLine(b);
        }
    }

3 值类型和引用类型

引用类型:string,数组,类

值类型:其它的,结构体

//无符号整型
    byte b1 = 1;
    ushort us = 1;
    uint ui = 1;
    ulong ul = 1;
//有符号整型
    sbyte sb = 1;
    short s = 1;
    int i = 1;
    long l = 1;
//浮点型
    float f = 1f;
    double d = 1.1;
    decimal de = 1.1m;
//特殊类型
    bool bo = true;
    char c = 'a';
    string str = "strs";
//复杂数据类型
//enum 枚举
//数组 (一维,二维,交错)
//类
//结构体

值类型和引用类型区别

值类型 在相互赋值时 把内容复制给对方 它变我不变

引用类型在相互赋值时 让两者指向同一个值 它变我也变

    //1、使用上的区别
    //值类型
    int a = 10;
    //引用类型
    int[] arr = { 1,};
 
    int b = a;
    int[] arr2 = arr;
    Console.WriteLine($"a={a},b={b}");
    Console.WriteLine($"arr[0]={arr[0]},arr2[0]={arr2[0]}");
 
    b = 20;
    arr2[0] = 0;
    Console.WriteLine("修改后:");
    Console.WriteLine($"a={a},arr2[0]={arr2[0]}");
    //值类型  在相互赋值时 把内容复制给对方 它变我不变
    //引用类型在相互赋值时 让两者指向同一个值 它变我也变
 
    //2、原因
    //它们在内存的存储方式是不同的
    //值类型存储在 栈空间,由系统分配,自动回收,小而快
    //引用类型存储在 堆空间,手动申请和释放,大而慢
 
    //new了新的内存空间,就和arr没关系了
    arr2 = new int[] {99,1,3};
    Console.WriteLine($"arr[0]={arr[0]},arr2[0]={arr2[0]}");

string的它变我不变

    //string的它变我不变
    string str1 = "123";
    string str2 = str1;
 
    //string特殊的地方在于重新赋值时会在堆中重新分配空间,因此它变我不变
    //在频繁对string重新赋值时,会产生内存垃圾
    str2 = "321";

4 函数

4.1 函数语法

    //无参无返回值
    static void SayHello()
    {
        Console.WriteLine("你好!");
    }
    //有参无返回值
    static void SayYourName(string name)
    {
        Console.WriteLine($"你的名字是:{name}");
    }
    //无参有返回值
    static string YourName()
    {
        return "tyy";
    }
    //有参有返回值
    static int Sum(int a,int b) => a + b;//一行代码的可以用=>表示返回值
 
    //有参有多返回值(用数组)
    static int[] SumAverage(int a,int b)
    {
        int sum = a + b;
        int avg = sum / 2;
        //int[] arr = { sum,avg };
        return new int[] {sum,avg};//一步返回数组需要new
    }
    
    SayHello();
    SayYourName("tyy");
    SayYourName(YourName());//一个函数的返回值作为另一个函数的参数传入
    Console.WriteLine(Sum(1,2));
    int[] arr = SumAverage(7,9);//也用数组接收函数的数组返回值
    Console.WriteLine($"{ arr[0]},{arr[1]}");

4.2 ref 和 out

作用:可以解决在函数内部改变外部传入的参数,函数里面改变外面也会改变

    //普通函数
    static void ChangeValue(int value)
    {
        value = 3;
    }
    static void ChangeArray(int[] arr)
    {
        arr = new int[] { 10,20,30 };//重新声明数组,外面没有改变
    }
    static void ChangeArrayValue(int[] arr)
    {
        arr[0] = 99;
    }
    
    //参数加ref
    static void ChangeValueRef(ref int value)//定义参数前面加上ref
    {
        value = 3;
    }
    static void ChangeArrayRef(ref int[] arr)
    {
        arr = new int[] { 10,30 };
    }
    
    //参数加out
    static void ChangeValueOut(out int value)//定义参数前面加上out
    {
        value = 33;
    }
    static void ChangeArrayOut(out int[] arr)
    {
        arr = new int[] { 100,30 };
    }
    
    int a = 1;
    ChangeValue(a);//a的值没有改变,因为int是值类型
    ChangeValueRef(ref a);//传入参数前也要加上ref或out,修改成功
    ChangeValueOut(out a);
    
    int[] arr1 = {1,3 };
    ChangeArray(arr1);//函数内重新声明数组,原数组元素值未改变
    ChangeArrayValue(arr1);//a[0]改变了
    ChangeArrayRef(ref arr1);//一起改变了
    ChangeArrayOut(out arr1);

4.3 变长参数 params 和参数默认值

4.3.1 变长参数

params int[]意味着可以传入任意n个参数,n可以为0,传入的参数存在arr数组中

  • params 关键字后面一定是数组

  • 数组可以是任意类型

  • 函数的参数可以是 其他类型的参数和 params 修饰的参数

  • 最多只能有一个 params 关键字,且一定放在最后一组参数

static int Sum(params int[] arr)
{
    int sum = 0;
    for(int i = 0; i < arr.Length; i++)
    {
        sum += arr[i];
    }
    return sum;
}
 
Sum();
Sum(1,12,235,23,1);//任意长的参数个数都可以

4.3.2 参数默认值

当函数调用时如果不传入参数,则使用默认值作为参数传入

每个参数都可以有默认值,有默认值的参数必须写在普通参数的后面

static void Speak(string str = "没什么说的")
{
    Console.WriteLine(str);
}
Speak();//使用默认参数
Speak("giao!");//使用传入参数

4.4 函数重载

在同一语句块中,函数的名字相同,但参数的数量、类型或顺序不同,与返回值无关

    static int Sum(int a,int b)
        {
            return a + b;
        }
        
    static int Sum(int a,int b,int c)//参数数量不同
    {
        return a + b + c;
    }
 
    static float Sum(int a,float b)//参数类型不同
    {
        return a + b;
    }
 
    static float Sum(float a,int b)//参数顺序不同
    {
        return a + b;
    }
 
    static int Sum(ref int a,int b)//ref和out也算重载,但一个重载的话另一个就不能重载了,两个中只取一
    {
        return a + b;
    }
    static int Sum(out int a,int b)//ref和out也算重载,但一个重载的话另一个就不能重载了
    {
        a = 1;
        b = 2;
        return a + b;
    }
 
    static float Sum(int a,params int[] arr)//变长参数重载
    {
        return 1;
    }

5 结构体

struct Student
{
    //public和private修饰结构体中的变量和函数,表示能否被外部使用
    //默认(啥都不写)为private
 
    //变量
    public int age;
    public bool sex;
    public int number;
    public string name;
 
    //函数方法 表现这个结构体的行为,不需要加static关键字
    public void Speak()
    {
        //函数中可以直接使用结构体声明的变量
        Console.WriteLine($"我的名字是{name},今年{age}岁");
    }
 
    //构造函数 用于在外部方便结构体的初始化
    //没有返回值,和结构体名字相同,必须有参数,声明构造函数必须对其中所有变量初始化
    public Student(int age,bool sex,int number,string name)
    {
        //this关键字,相同变量名字时来区分自己和参数
        this.age = age;//必须初始化
        this.sex = sex;
        this.number = number;
        this.name = name;
    }
}
 
    Student s1;
    s1.age = 10;//public才能在外部使用变量和函数
    s1.sex = false;
    s1.number = 1;
    s1.name = "tyy";
    s1.Speak();

原文地址:https://blog.csdn.net/lwf3115841/article/details/129709045

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


项目中经常遇到CSV文件的读写需求,其中的难点主要是CSV文件的解析。本文会介绍CsvHelper、TextFieldParser、正则表达式三种解析CSV文件的方法,顺带也会介绍一下CSV文件的写方法。 CSV文件标准 在介绍CSV文件的读写方法前,我们需要了解一下CSV文件的格式。 文件示例 一
简介 本文的初衷是希望帮助那些有其它平台视觉算法开发经验的人能快速转入Halcon平台下,通过文中的示例开发者能快速了解一个Halcon项目开发的基本步骤,让开发者能把精力完全集中到算法的开发上面。 首先,你需要安装Halcon,HALCON 18.11.0.1的安装包会放在文章末尾。安装包分开发和
这篇文章主要简单记录一下C#项目的dll文件管理方法,以便后期使用。 设置dll路径 参考C#开发奇技淫巧三:把dll放在不同的目录让你的程序更整洁中间的 方法一:配置App.config文件的privatePath : &lt;runtime&gt; &lt;assemblyBinding xml
在C#中的使用JSON序列化及反序列化时,推荐使用Json.NET——NET的流行高性能JSON框架,当然也可以使用.NET自带的 System.Text.Json(.NET5)、DataContractJsonSerializer、JavaScriptSerializer(不推荐)。
事件总线是对发布-订阅模式的一种实现,是一种集中式事件处理机制,允许不同的组件之间进行彼此通信而又不需要相互依赖,达到一种解耦的目的。&#xA;EventBus维护一个事件的字典,发布者、订阅者在事件总线中获取事件实例并执行发布、订阅操作,事件实例负责维护、执行事件处理程序。
通用翻译API的HTTPS 地址为https://fanyi-api.baidu.com/api/trans/vip/translate,使用方法参考通用翻译API接入文档 。&#xA;请求方式可使用 GET 或 POST 方式(Content-Type 请指定为:application/x-www-for
词云”由美国西北大学新闻学副教授、新媒体专业主任里奇·戈登(Rich Gordon)于2006年最先使用,是通过形成“关键词云层”或“关键词渲染”,对文本中出现频率较高的“关键词”的视觉上的突出。词云图过滤掉大量的文本信息,使浏览者只要一眼扫过文本就可以领略文本的主旨。&#xA;网上大部分文章介绍的是使用P
微软在.NET中对串口通讯进行了封装,我们可以在.net2.0及以上版本开发时直接使用SerialPort类对串口进行读写操作。&#xA;为操作方便,本文对SerialPort类做了一些封装,暂时取名为**SerialPortClient**。
简介 管道为进程间通信提供了平台, 管道分为两种类型:匿名管道、命名管道,具体内容参考.NET 中的管道操作。简单来说,匿名管道只能用于本机的父子进程或线程之间,命名管道可用于远程主机或本地的任意两个进程,本文主要介绍命名管道的用法。 匿名管道在本地计算机上提供进程间通信。 与命名管道相比,虽然匿名
目录自定义日志类NLog版本的日志类Serilog版本的日志类 上个月换工作,新项目又要重新搭建基础框架,把日志实现部分单独记录下来方便以后参考。 自定义日志类 代码大部分使用ChatGPT生成,人工进行了测试和优化,主要特点: 线程安全,日志异步写入文件不影响业务逻辑 支持过期文件自动清理,也可自
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机自动启动的两种常用方法](https://blog.csdn.net/weixin_42288432/article/details/120059296),将里面中的第一种方法做了封装成**AutoStart**类,使
简介 FTP是FileTransferProtocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。 FTP
使用特性,可以有效地将元数据或声明性信息与代码(程序集、类型、方法、属性等)相关联。 将特性与程序实体相关联后,可以在运行时使用反射这项技术查询特性。&#xA;在 C# 中,通过用方括号 ([]) 将特性名称括起来,并置于应用该特性的实体的声明上方以指定特性。
# 简介 主流的识别库主要有ZXing.NET和ZBar,OpenCV 4.0后加入了QR码检测和解码功能。本文使用的是ZBar,同等条件下ZBar识别率更高,图片和部分代码参考[在C#中使用ZBar识别条形码](https://www.cnblogs.com/w2206/p/7755656.htm
C#中Description特性主要用于枚举和属性,方法比较简单,记录一下以便后期使用。 扩展类DescriptionExtension代码如下: using System; using System.ComponentModel; using System.Reflection; /// &lt;
本文实现一个简单的配置类,原理比较简单,适用于一些小型项目。主要实现以下功能:保存配置到json文件、从文件或实例加载配置类的属性值、数据绑定到界面控件。&#xA;一般情况下,项目都会提供配置的设置界面,很少手动更改配置文件,所以选择以json文件保存配置数据。
前几天用SerialPort类写一个串口的测试程序,关闭串口的时候会让界面卡死。网上大多数方法都是定义2个bool类型的标记Listening和Closing,关闭串口和接受数据前先判断一下。我的方法是DataReceived事件处理程序用this.BeginInvoke()更新界面,不等待UI线程
约束告知编译器类型参数必须具备的功能。 在没有任何约束的情况下,类型参数可以是任何类型。 编译器只能假定 System.Object 的成员,它是任何 .NET 类型的最终基类。 如果客户端代码使用不满足约束的类型,编译器将发出错误。 通过使用 where 上下文关键字指定约束。&#xA;最常用的泛型约束为
protobuf-net是用于.NET代码的基于契约的序列化程序,它以Google设计的“protocol buffers”序列化格式写入数据,适用于大多数编写标准类型并可以使用属性的.NET语言。&#xA;protobuf-net可通过NuGet安装程序包,也可直接访问github下载源码:https:/
工作中经常遇到需要实现TCP客户端或服务端的时候,如果每次都自己写会很麻烦且无聊,使用SuperSocket库又太大了。这时候就可以使用SimpleTCP了,当然仅限于C#语言。&#xA;SimpleTCP是一个简单且非常有用的 .NET 库,用于处理启动和使用 TCP 套接字(客户端和服务器)的重复性任务