Csharp基础

之前是学java的,会带有java的想法;

编译软件visual studio

  • Debug: 可以进行断点调试,点击启动开启;
  • **启动:**绿色三角为启动按钮,左边启动是在线窗口启动,右边启动会打开一个新的启动窗口;
  • 基础学习:了解三种文件项目即可;
    • 在这里插入图片描述
  • 类库:类库项目通常包含可重用的代码,例如类、方法、函数等。这些项目不会生成可执行文件,而是编译成可供其他应用程序引用的库;类库项目用于封装和组织代码,以便其他项目可以共享和重用这些代码。(类似于手写包,使用时需要在引用中引入自己写的类库,也能够直接引入系统自带的)
  • **控制台应用:**控制台应用是一种基于文本的应用程序,通常在命令行窗口中运行。它们用于执行文本输入和输出,通常用于测试、脚本和小型工具;控制台应用程序通常包含 Main 方法,是程序的入口点,它从命令行接受输入参数并向控制台输出结果。(就是启动main方法控制台输出,跟Dev C++差不多)
  • window:窗体应用是一种图形用户界面(GUI)应用程序,通常在 Windows 操作系统中运行。它们使用窗体、按钮、文本框等可视元素来与用户交互;窗体应用程序通常包含一个主窗体,该窗体包含应用程序的用户界面。用户可以与窗体中的控件进行交互。(Form对象的使用,启动会生成一个窗口)

在这里插入图片描述

基本数据类型

在这里插入图片描述

  • 含有非负数据类型:byte,ushort,uint,ulong
  • 在csharp中没有工具类,可以通过基本数据类型进行参数类型转换,并且可以设置为空int? intdemo = null;
  • 字符串转换成基本数据类型代码组成:基本数据类型.Parse() int number2 = int.Parse(Console.ReadLine());
数据类型符号字节范围
整型Byte(比特位)1字节,8位0-255(2^8
SByte(有符号整型)1字节,8位-128-127(有数字0
short2字节,16位-32768-32767
int4字节-2,147,483,648-2,147,483,647
long8字节-263-263-1
浮点型float4字节
double8字节
字符型char(\u输出unicode2字节
布尔类型bool1字节

运算符执行顺序

注意:&执行顺序是在|的前面

在这里插入图片描述

解释a = a+ b 和 a += b的区别:=会创造新的值 , +=则会将新值存回a

  1. a = a + b
    • 这是一个简单的赋值语句,将 a 的当前值与 b 相加,然后将结果重新赋值给 a
    • 这将创建一个新的值,并将其分配给变量 a,因此 a 的值会发生变化。
    • 适用于任何数据类型,只要支持加法操作。
  2. a += b
    • 这是一个复合赋值操作符,用于将 a 的当前值与 b 相加,然后将结果存回 a
    • 这不会创建新的值,而是在现有值的基础上执行相应的操作。因此,它通常比 a = a + b 更高效。

基础业务逻辑

  • 条件判断 if(),switc(){case :{ break;}defaule {break;}}
  • 循环:for循环;while;do{}while();goto

条件判断

If 判断: if(条件){}else if(条件) else{}。条件必须符合布尔类型,else if()可以写多个,if和else只能存在一个

例题:成绩是否合格

int score = int.prase(Console.ReadLine());//window窗口输入,并将输入内容转换成int
if (score >= 90)
{
    Console.WriteLine("优秀");
}
else if (score >= 80)
{
    Console.WriteLine("良好");
}
else if (score >= 70)
{
    Console.WriteLine("中等");
}
else if (score >= 60)
{
    Console.WriteLine("及格");
}
else
{
    Console.WriteLine("不及格");
}

switch() case: switch(参数){ case 标签: {代码;break;} ··· default:{ 代码;break;} }传入的参数会与case后的标签进行比较,如果相等则会执行代码快内容

例题,星期几

使用swtich让用户在控制台中分别录入2个数字,1个运算符,根据运算符计算数字。

string day = Console.ReadLine(); // 你可以根据需要设置不同的星期几

switch (day)
{
    case "Monday":
        Console.WriteLine("今天是星期一。");
        break;
    case "Tuesday":
        Console.WriteLine("今天是星期二。");
        break;
    case "Wednesday":
        Console.WriteLine("今天是星期三。");
        break;
    case "Thursday":
        Console.WriteLine("今天是星期四。");
        break;
    case "Friday":
        Console.WriteLine("今天是星期五。");
        break;
    case "Saturday":
        Console.WriteLine("今天是星期六。");
        break;
    case "Sunday":
        Console.WriteLine("今天是星期日。");
        break;
    default:
        Console.WriteLine("不是有效的星期几。");
        break;
}

//1.使用swtich让用户在控制台中分别录入2个数字,1个运算符,根据运算符计算数字。
            Console.WriteLine("输入第一个数字");
            int number1 = int.Parse(Console.ReadLine());
            Console.WriteLine("输入第二个数字");
            int number2 = int.Parse(Console.ReadLine());
            Console.WriteLine("输入运算符号");
            string symbol = Console.ReadLine();

            switch (symbol)
            {
                case "+": { Console.WriteLine($"{number1}+{number2}={number1 + number2}"); break; }
                case "-": { Console.WriteLine($"{number1}-{number2}={number1 - number2}"); break; }
                case "*": { Console.WriteLine($"{number1}*{number2}={number1 * number2}"); break; }
                case "/": { Console.WriteLine($"{number1}/{number2}={number1 / number2}"); break; }
                default: { Console.WriteLine("你所输入符号不对"); break; };
            }

循环

注意点:关键字

break,直接结束break所在的循环,如果循环嵌套,增结束break所在的最内层循环;

continue;则是结束该次循环,进入下一次循环;

for循环

组成for + (部分一;部分二;部分三){};例子for(int i = 0; i < 10; i++){}

部分一用来定义参数初始值。部分二是条件,条件成立执行代码块内容,部分三常用于部分一定义的初始值进行自增,因为每部分都是通过分号“;”进行分割,所以执行顺序从左到右部分一二三都可以省略不写

  • for(;😉:没有条件,默认符合,会进入死循环,可以通过break结束循环;
  • for(int x = 0 ; ; x++):没有条件,但是初始参数x会在该循环自增1;
  • for(int x = 0; 条件; x++)这个条件只要代码返回时布尔类型都是可以放在这里,不用按照标准格式对x进行大于小于判断,主要是提醒编码的灵活性;下方例子就是这样

例题:任意输入两个数字 之和 大于 100 积一分 反之 扣一分 如果分数小于-10或大于10 输入结束

        int sum = 0;
        for (int i = 0; sum < 10 && sum > -10; i++)
        {
            //if (sum > 10 || sum < -10)
            //{
            //    break;
            //}
            Console.WriteLine("输入第一个数字");
            int number2_1_1 = int.Parse(Console.ReadLine());
            Console.WriteLine("输入第二个数字");
            int number2_2_1 = int.Parse(Console.ReadLine());
            sum = number2_1_1 + number2_2_1 > 100 ? ++sum : --sum;
            Console.WriteLine($"第{i}局,分数为{sum}");
        }
while

while(条件){代码},根据代码从上到下执行,先判断,条件为true则执行代码,否则直接跳过代码块;也可以通过break跳出循环

例题:任意输入两个数字 之和 大于 100 积一分 反之 扣一分 如果分数小于-10或大于10 输入结束

        int sum_while = 0;
        while(sum_while < 10 && sum_while > -10)
        {
            Console.WriteLine("输入第一个数字");
            int number2_1_2 = int.Parse(Console.ReadLine());
            Console.WriteLine("输入第二个数字");
            int number2_2_2 = int.Parse(Console.ReadLine());
            sum_while = number2_1_2 + number2_2_2 > 100 ? ++sum_while : --sum_while;
            Console.WriteLine($"while循环分数为{sum_while}");
        }
do{}while()

do{代码块}while(条件)与while区别,因为代码块是放在前面,所以实现执行代码块,后进行条件判断

例题:任意输入两个数字 之和 大于 100 积一分 反之 扣一分 如果分数小于-10或大于10 输入结束

            int sum_do_while = 0;
            do
            {
                Console.WriteLine("输入第一个数字");
                int number2_1_3 = int.Parse(Console.ReadLine());
                Console.WriteLine("输入第二个数字");
                int number2_2_3 = int.Parse(Console.ReadLine());
                sum_do_while = number2_1_3 + number2_2_3 > 100 ? ++sum_do_while : --sum_do_while;
                Console.WriteLine($"do_while循环分数为{sum_do_while}");
                //if (sum_do_while >= 10 || sum_do_while <= -10)
                //{
                //    break;
                //}
            } while (sum_do_while < 10 && sum_do_while > -10);
goto控制流(在java中不支持)

标签: goto 标签;使用goto首先要在使用前定义一个标签例如gotostart:( 标签名+冒号),使用标签 goto gotostart;(goto 你之前定义的标签名+分号);然而,应该小心使用goto,因为它可能导致不易理解和维护的代码。

例题:任意输入两个数字 之和 大于 100 积一分 反之 扣一分 如果分数小于-10或大于10 输入结束

        int num_goto = 0;
        gotoDemo:
        
            Console.WriteLine("输入第一个数字");
            int number2_1 = int.Parse(Console.ReadLine());
            Console.WriteLine("输入第二个数字");
            int number2_2 = int.Parse(Console.ReadLine());
        num_goto = number2_1 + number2_2 > 100 ? ++num_goto : --num_goto;
            Console.WriteLine($"goto循环分数为{num_goto}");
        if (num_goto < 10 && num_goto > -10)
        {
            goto gotoDemo;
        }

修饰符

静态:

  1. 静态方法直接不能调用非静态方法:在Java中,静态方法(static 方法)可以通过类名.静态方法()调用,但不能直接调用非静态方法(实例方法),因为静态方法在类加载时就存在,而非静态方法依赖于类的实例。如果要在静态方法中调用非静态方法,您需要首先创建类的实例,然后通过实例调用非静态方法。
  2. static修饰的代码会在启动时加载:在Java中,(方法区会存放类信息,而static修饰的方法可以通过类名调用并不需要实例化,所以在记载类时会将stati修饰的信息加载到方法区中),static 关键字用于创建静态成员,而不是代码块。静态成员(静态字段和静态方法)在类加载时初始化,并且只初始化一次。静态代码块是一种特殊的初始化块,可以用来在类加载时执行额外的初始化操作,但它不是普通的Java代码段。正常的Java代码段在类加载后不会自动执行。

介绍原因,正常类的属性、方法使用需要实例化对象,static则是在加载类时就会加载;理清加载调用的顺序;

  • 权限修饰符:

    • public,internal, 可以修饰命名空间的下一级类,
    • public,protected,private常用于修饰属性、方法,不能直接修饰namespace的下一级类,但是能修饰内部类,就是java中匿名内部类本部分;通过权限修饰符修饰的代码,是被保护起来,程序是能找到的,但是无法访问;比如在java中private修饰的方法或属性是可以通过反射获取到;

    在C#中默认声明的类时internal;

    internal在java中没有,在java中声明的类默认是私有的

  • static(静态): 静态成员(静态方法、静态字段)属于类而不是实例。它们可以通过类名直接访问,而不需要创建对象。

  • **final(最终):**不可变化是他最大特点, 被标记为final的类不能被继承,被标记为final的方法不能被重写,被标记为final的字段是不可变的。 所以接口和抽象类不能使用final修饰

修饰类修饰符

用于修饰类,常见类接口,抽象类,枚举;

  • 接口interface: interface修饰的类,类中只有抽象方法,不能实例化对象,需要是实现类实现该接口,通过多态进行对象实例化;
  • 抽象类abstract: abstract修饰的的类,与接口的区别,抽象类可以有抽象方法也有非抽象方法。 抽象类不能被实例化,只能被继承。子类必须实现(覆盖或重写)抽象类中的所有抽象方法,除非子类自己也是抽象类。
  • 不能使用final修饰符修饰;
  • 枚举enum: 枚举是经典的单例模式,但是博主觉得java中枚举用法更方便一点
  • interface(接口): 接口不能被实例化,只有抽象方法,这些方法必须在实现类实现。
  • abstract(抽象): 抽象类不能被实例化,它通常包含抽象方法,这些方法必须在子类中实现。
  • enum(枚举): 简化代码开发,内部声明的变量一般为大写,都是单例;
    • 在csharp中枚举默认参数是整形,赋值一般赋值整数类型,可以赋值字符串但是很麻烦
    • 在java中枚举赋值字符串,声明final修饰的属性,定义代参构造方法,声明大写对象时通过构造放声明对象,如WORKDAY(“工作日”)
  • struct: 举例,二维表的x,y轴定义;

权限修饰符

  1. public: 成员对所有代码可见,没有限制。其他代码可以在任何地方访问 public 成员。
  2. private: 成员仅对定义它们的类内部可见。其他类无法访问 private 成员。
  3. protected: 成员对定义它们的类及其派生类可见。其他类无法访问 protected 成员。
  4. internal:修饰类; 成员对同一程序集内的所有代码可见。它是默认访问修饰符,如果不指定访问修饰符,则成员默认为 internal。
  5. protected internal: 成员对同一程序集内的所有代码和派生类可见。
  6. private protected: 成员对同一程序集内定义它的类的派生类可见,但对其他类不可见。这是 C# 7.2 版本引入的新修饰符。

注意,在不同项目集使用时,注意要在引入中引入项目,并且在文件头部通过using引入命名空间

理解文件在项目中不同位置

  • 命名空间: 命名空间是一种用于组织和分类代码的方法。它允许你在代码中创建一个逻辑上相关的组,以便更好地管理和组织类、方法和其他成员;在useing时使用,可以通过命名空间使用该命名空间内的类方法;
  • 程序集: 程序集是.NET中的一个重要概念,它是一种部署和版本控制的单元。程序集可以包含一个或多个文件,包括可执行文件(例如.exe)和动态链接库(.dll)。程序集也包括元数据,用于描述程序集中的类型和成员。
  • 解决方案: 解决方案是一种用于组织多个项目的方式,通常包含一个或多个项目文件。在Visual Studio等开发环境中,你可以创建解决方案,然后将一个或多个项目添加到解决方案中。解决方案有助于管理和构建多个项目,并允许它们共享配置和设置。

函数(方法)

在类中定义的方法在C、C++、C#会称为函数,使用规则 权限修饰符+返回值类型+方法名(){};可以使用return跳出函数

方法中形参数据更改解释为什么不会影响传入的实参

在这里插入图片描述

参数操作

  • ref: 在c#会有类似C中的指针功能,通过指针可以直接获取到地址所存储的值

  • out: 修饰参数不能参与运算(,因为未对该参数声明空间,正常形参是必须要传入一个声);用于向方法传递参数,并允许方法在执行过程中修改参数的值。通常,方法的参数是通过值传递的,这意味着方法接受参数的值,但不会修改原始值。然而,当你使用 out 参数修饰符时,方法可以修改参数的值并将修改后的值传递回调用者。

  • out和ref,普通形参区分:

    相同:都可以修改参数中的原始值,

    区别:1. ref是指针指向数据的原始值,out是回修改参数的值并将修改后的值传递给传入的变量;

    1. ref和普通形参需要初始值,out 形参不需要初始值;因为ref是指向该参数的原始值而不是存储地址,所以需要指向存储空间所存储的数据,而out是将操作后的值返回给该参数,所以并不需要初始化;
    2. ref 参数:ref 和普通参数在方法内部可以保持其初始值,并且方法可以修改该值。out 参数:out 参数在方法内部不需要保持其初始值,因为方法必须为其分配一个新值。
    3. 普通形参是最常见的形参类型,它们是方法的输入参数,用于传递数据给方法。普通形参传递的是值的副本,这意味着方法无法修改原始值,只能操作传递进来的副本。
  • **params:**在params参数必须定义在参数列表最后面。params必须对一维数组描述;params只能在一个方法中 定义一个一维数组

     static void Main(string[] args)
        {
            ParamtesDemo("223班级", "张三", "李四", "王五", "赵六");//班级后的参数符合string类型,会存放到该方法的数组参数,在java中有...可以实现不限制方法参数个数;

            int a = 5; int b = 5;
            string c;//out 的使用,c变量可以不赋值,在java中不能这样会报错
            demoRef(ref a, ref b);
            demoOut(a, b,out c);
            Console.WriteLine($"{a}:{b}:{c}");

        }

	public static void demoRef(ref int a,ref int b)
    {
        a++;
        b++;
    }
    
    public static void demoOut(int a,int b,out string c)
    {
        a++;
        c = "a";
        b++;
    }
    static void ParamtesDemo(string className, params string[] names)
    {
        string tempStr = "";
        foreach (string name in names)
        {
        	tempStr += name;
        }
        Console.WriteLine($"{className}的学生有:{tempStr}");
    }

委托,事件

委托(Delegate)

  • 委托是一种类型,用于表示对方法的引用。
  • 它允许你将方法视为一个参数,将方法的引用传递给其他方法,然后可以在后续调用委托时执行该方法。
  • 委托用于实现回调函数和事件处理。
  • 委托的声明类似于方法,但可以在运行时关联不同的方法。
  • 委托的调用可以使用invoke() 委托对象.invoke();

事件(Event)

  • 事件是一种特殊的委托,用于通知其他部分(通常是其他对象)发生了某个事件。

  • 事件定义了触发事件的方式,其他对象可以注册对事件的监听,当事件发生时,注册的监听器方法将被调用。

  • 事件通常用于实现发布-订阅模型,其中一个对象发布事件,而其他对象订阅并响应事件。

    类似订阅模式:解释事件与委托关联的作用

    **作用:**常见的作用当数据库数据更改时,记录数据更改事件并响应;

两者合作使用,类似与spring中的aop虽然差异还是比较多的,

	delegate void MyEventHandler();//直接调用可以将实例方法直接进行赋值,然后通过invoke执行

    internal class Program
    {
        //定义实例方法
        public static void demoDelegate()
        {
            Console.WriteLine("delegate 委托直接赋值");
        }
        static void Main(string[] args)
        {
			//委托赋值
            MyEventHandler myEventHandler = demoDelegate;
			//委托执行
            myEventHandler.Invoke();
           
            //委托与事件结合
            PublicDemo demo = new PublicDemo();
            DelegateDemo d = new DelegateDemo();

            d.delegateDemoDelegate += demo.demo;
            d.delegateDemoDelegate += demo.demo2;

            demo.demo2();
            demo.demo();
            d.demo1();
        }
//1.定义一个委托;委托可以将方法当作参数进行传递
//  定义的委托 需要通过event作为类型接收
delegate void DelegateDemoDelegate();

//2. 定义委托增强
internal class DelegateDemo
{
    //2.1 定义事件
    public event DelegateDemoDelegate delegateDemoDelegate;

    //2.2 委托方法实现
    public void demo1()
    {

        Console.WriteLine("demo1对委托方法进行增强");

        if (delegateDemoDelegate != null)
        {
            delegateDemoDelegate();
        }
    }        
}
//3.定义实例对象
public class PublicDemo
{
    public void demo()
    {
        Console.WriteLine("实例demo;");
    }
    public void demo2()
    {
        Console.WriteLine("实例demo2:");
    }
}

    

数组

存储相同数据类型的一种特殊存储方式,长度固定,需要[]

在C#使用数组一维数组,

  • 数据类型[] 变量名 = new 数据类型[length];**该方式length必须要声明,**该方式是要在内存空间声明长度为length的空间int[] arr = new int[5];
  • 数据类型[] 变量名 = {数据1,…… ,数据n} **该方式会将数据存放到内存空间中,数据类型要符合声明的类型,**通过{}可以将包裹数据存放到数组中,数据通过,分隔,int[] arr = {1,2……,n}

与java不同:多维数组

声明方式:

  • csharp基本使用:int[,] arr = new int[2,3]; int[,] arr = {{1,1,1},{2,2,2},{3,3,3}};通过在[]添加,来判断是几维数组;

  • java二维数组:是通过[]来判断是几维数组

    int[][] arr = new int[3][3];int[][] arr = {{1,1,1},{2,2,2},{3,3,3}};
    

遍历方式:

        int[,] arr = { { 1, 1, 1 }, { 2, 2, 2 }, { 3, 3, 3 } };
		//c#遍历
        for (int i = 0; i < arr.GetLength(0); i++)
        {
            for (int j = 0; j < arr.GetLength(1); j++)
            {
                 Console.Write(arr[i,j]+" , ");
            }s
            Console.WriteLine();
        }

java是通过[]来判断数组是多维数组

int[][] arr = {
        {1,1,1},{2,2,2},{3,3,3}
};

for (int[] ints : arr) {
    for (int anInt : ints) {
        System.out.print(anInt+",");
    }
    System.out.println();
}
for (int i = 0; i < arr.length; i++) {//arr.length判断是几维数组
    for (int j = 0; j < arr[i].length; j++) {//arr[i].lengrh()是用于获取二维数组中特定行(索引 i)的长度
        System.out.println(arr[i][j]+",");//获取到数组下标为i,j的值
    }
    System.out.println();
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值