C# 【未完成】

VIsual Studio 安装

直接下载社区版本,免费

Vlsual Studio快捷键

https://learn.microsoft.com/zh-cn/visualstudio/ide/default-keyboard-shortcuts-in-visual-studio?view=vs-2022&utm_source=vshelp

CLR 和 CLI

百度OK?

image-20230417192747867

image-20230417192803279

反编译软件

一般在C盘的 X86下面的Microsoft SDKs下面的windows Vxx 下面的bin中的 ildasm.exe

数据类型

13种基本数据类型

文档:https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/builtin-types/built-in-types

那些有符号的都是第一位作符号位的

然后设计到钱的话,用decimal更精确

  • bool表示布尔值,真或假
  • char则表示一个UTF-16标准下的Unicode 字符
  • char无法表示中文:中文标准是GBK、不属于UTF-16
  • 中文得用string类型,emoji也可以,其实是把多个Unicode码拼接起来【String不是基本类型哦】

image-20230417194824283

image-20230417194653273

注意!

C 和 C++ 开发人员请注意,在 C# 中,bool 不能转换为 int

HElloWorld项目解刨

using System;   //用 using 引入 命名空间 namespace

namespace HelloWorld        //这个就是命名空间 namespace
{
    class Program           // 类
    {
        static void Main(string[] args)     //主方法
        {
            Console.WriteLine("HelloWorld");       //语句
        }
    }
}
 

System.Console操作

  • Wirte(参数)
  • WirteLine(参数)
  • Read()
  • ReadKey()
  • ReadLine()
  • Clear()

String一些输出操作

@ 和 $

条件判断语句

都和Java一样

  • if else
  • switch
  • 三元运算符 :?

循环

都和Java一样

  • for
  • while
  • do-while

方法

方法签名

image-20230417201748294

访问修饰符

image-20230417201832780

声明修饰符

image-20230417201903820

返回类型 和 方法名称 和 参数

image-20230417202002933

方法规则:

  • 静态方法只能由静态方法调用 和 Java一样
  • 如果一个方法不返回任何值,那么就默认返回void
  • 形参和实参 也和 Java一样,这里不讲解
  • 可以用方法表达式
    • 即用 => 来表示方法,代替掉了 花括号。

值传参,引用传参,输出传参

  • 在参数前面加上 ref ,那么就是引用数据传递。
    • 【传递变量的内存地址】
    • 【注意使用和定义都要加上 ref】
    • 【变量必须先定义赋值】
  • 在参数前面加上 out ,那么就是输出传参。
  • 【传递变量的内存地址】【注意使用和定义都要加上 out】
  • 【功能和引用传参一样,但是不一样在于: 变量可以不赋值】

例:

using System;
namespace HelloWorld
{
    class Program
    {
        public static void Swap(ref int a, ref int b)
        {
            a = 100;
            b = 200;
        }
        public static void Out(out int z)
        {
            z = 999;
        }
        static void Main(string[] args)
        {
            int x = 1;int y = 2;
            System.Console.WriteLine(x);    // 1
            System.Console.WriteLine(y);    // 2
            Swap(ref x, ref y);
            System.Console.WriteLine("使用swap后:" +x);    // 100
            System.Console.WriteLine("使用swap后:" + y);   // 200
            int z;  //可以不赋值
            Out(out z);
            Console.WriteLine(z);       //999
        }
    }
}

面向对象

dynamic 是不确定类型数据

要 新建一个对象,直接:

dynamic obj = new {x = 15,y = 10};

其中 dynamic是不确定类型,x 和 y 相当于对象的属性,并初始了值。

创建类

public class Point{		//也是存在修饰符的 这里是public 和Java一样
	public int x;	//成员变量
    ...
    //方法
    public int MethodTest(int a,int b)=>System.Console.WriteLine(a);
}

创建对象

ClassName objectname = new ClassName();
         public static void Main(string[] args)
        {
            Point point = new Point();
            point.x = 123;
            point.MethodTest();
        }
    }

    public class Point  //也是存在修饰符的 这里是public 和Java一样
    {
        public int x;   //成员变量
        public void MethodTest() => System.Console.WriteLine(this.x);                       //方法
    }

构造、重载、访问修饰、封装、重写、继承

构造:

Point a = new Point {x = 1, y = 2};	//可以这样进行构造复制,这是C#独有的

//下面的是构造方法,和Java一样,其他也和Java一样
            public Point()
            {
                this.x = 15;
                y = 10;
            }

重载也和Java一样


访问修饰

  • public 和 private 和Java一样

  • protected:只能被自己或继承自己的子类访问 也和Java一样

  • internal:访问范围:只能在同一个项目的程序集中

  • 两个项目之间可以建立引用,用using进行导入

  • 但是如果用了 internal 那么项目就不能被引用了。


封装可以get、set函数

独有特点:【下面相当于封装了get和set 方法,这叫“属性”】

规范:一般私有成员变量前面加个_下划线。

        public class Point
        {
            // 成员变量x轴,使用属性
            private int _x;
            public int X		//规范用大写
            {
                get { return this._x; }
                set
                {
                    if (value < 0)
                    {
                        throw new Exception("value不能小于0");
                    }
                    this._x = value;
                }
            }
        }
-------------------------------------------------------------------------------------
    		//还可以:
            // 成员变量Z,自动生成getter、setter
            public int Z { get; set; }
			
//使用:
            Point a = new Point(15, 10);
            a.Z = 111;
            Console.WriteLine(a.Z);
            //使用的时候自动会给值的 非常的方便哈
            point.X = 30;
            Console.WriteLine(point.X);

const常量、 、只读read-only、只写write-only

只读和只写其实就是自动封装get/set的时候,如果只给一个那么就是 只读/只写

		//还可以:
        // 成员变量z轴,自动生成getter、setter
        public int Z { get; set; }
	    
		//只读:
		public int T { get; } = 123;        // 123就是初始的值,如果没有定义,默认为类型的初始值
		//也可以在构造函数中更改给他初始值,但是不能在普通方法中更改!
		
		
		//只写:
		private int _y; //如果是只写的 必须存在私有属性!		如果要读,只能在方法内部读			

            public int Y
            {
                set { _y = value; }
            }

const常量:

其实就是不能修改,除了初始化,定义后就不能修改了!

readonly变量:

//readonly 变量
public readonly int b;

和const差不多,但是不同之处:

  1. const 定义的时候一定要初始化,否则后面就改不了【在构造也改不了!】,readonly 定义的时候可以先不赋值,构造函数或初始化赋值后, 后面就不能赋值了!
  2. Const在定义前就能定下来,readonly 就不是。 【const 比 readonly 性能好一点】

索引和范围

image-20230418205255648

^是倒数的意思, ^1是倒数第一位

image-20230418205341376

0..3 的长度就是3 ,即可: 0、1、2

索引和范围都可以进行下面操作:

            Index k = ^1;
            Console.WriteLine(words[k]);
Range p = 0..3;
var list = words[p];

类索引

image-20230418210413549 image-20230418210553869
        private string[] _g = new string[]
        {
                // index from start index from end
	             "The",  // 0     ^9
	             "quick", // 1     ^8
	             "brown", // 2     ^7
	             "fox",  // 3     ^6
	             "jumped", // 4     ^5
	             "over",  // 5     ^4
	             "the",  // 6     ^3
	             "lazy",  // 7     ^2
	             "dog"  // 8     ^1
        };    // 9 (or words.Length) ^0

        public string this[int index]
        {
            get
            {
                return _g[index];
            }
            set
            {
                _g[index] = value;
            }
        }

// 下面是重载 根据内容查找位置 不再是int类型的 index 了
public int this[string name]
{
    get
    {
        return Array.IndexOf(_g, name);
    }
}

Partial Class局部类

image-20230418210834089

注意:两个类都需要添加 partial关键字,然后两个类的名字也是一样的。里面的成员和方法也是共享的。

image-20230418213051641

注意事项:

image-20230418213104462

继承

C# 的继承用 :冒号来,Object是所有类的父类,然后其他和Java一样

复合 Composition

描述两个class之间的关系,不同类之间包含和被包含的关系

解决代码复用问题

完成对象间的依赖注入,适合大型项目的开发

。。。其实就是emmmm....UML的符合,设计模式。

构造方法的继承

初始化时候,基类的构造方法总是首先运行,不会被继承,在派生类中需要重新定义 【和Java一样】

但是呢,C# 是不存在super的,存在的是 :base()可以进行选择父类的构造方法

本来默认就调用父类的无参构造,现在可以用 :base() 进行选择,【Java是用super()方法】

        public class Staff
        {
            public Staff()
            {
                Console.WriteLine("员工类初始化");
            }

            public int Number { get; set; }
            
            public Staff(int number)		//相当于用base()选择了这个构造方法
            {
                Number = number;
            }
        }

public class Manager : Staff
        {
            public Manager()
            {
                Console.WriteLine("经理类初始化");
            }
            public Manager(int number):base(456)
            {
                
            }
        }

static void Main(string[] args)
{
    var manager = new Manager(123);
    Console.WriteLine(manager.Number);
}

向上转型,向下转型

其实和Java的一样。

as关键词,可以可以进行向下转型?如果失败不会抛出异常,会让对象为null。

is关键词,检查对象类型,查看是不是同一个类?

装箱boxing和拆箱

值类型、引用数据类型

保存区:栈、堆

  1. 值类型保存在栈 stack,例:byte/int/float/char/bool 和结构 struct

  2. 内存由编译器自动分配,程序结束内存会自动被回收

  3. 引用类型保存在堆 heap

  4. 程序员自己手动释放内存,Java和C#都自动垃圾回收机制

  5. Class、对象一般来说都保存在 heap 中

装箱原理和Java一样,就是值类型转为引用类型的转换过程,保存的位置也是从 stack ——> heap

拆箱则相反。

装箱和拆箱都存在性能问题。

案例:

比如 array中的Add,如果加入正整数1 ,那么就是把1自动进行了装箱。

尽量避免即可。可以用泛型进行避免。

虚方法和重写

访问修饰符 virtual 函数返回类型 函数名(参数表) {函数体};

virtual关键字标记一个virtual。

修改基类的某些方法的执行逻辑

使用override关键词进行重写

其实虚方法就是类似Java中的父类中被重写的方法,Java不存在虚方法的。

C# 中虚方法被重写用 override关键字进行重写即可。

//下面就是重写了 Shape中的 虚方法 Draw()
public class Trangle : Shape
    {
        public override void Draw()
        {
            Console.WriteLine("画三角");
        }
    }

抽象类与抽象成员

abstract 关键字

可以修饰类、属性、方法

抽象的属性或方法是不能有代码实现的

如果有抽象成员,那么类也一定要是抽象的

如果有继承派生、那么一定要实现其中所有的抽象方法和抽象属性

抽象类不可以实例化

其实和Java也一样

sealed类与sealed成员

密封类和密封成员

sealed修饰符,可以修饰class 和 类方法

功能是防止类继承、派生类重写

所以就是如果修饰类,那么该类不能被继承

如果修饰方法,那么该方法不被重写

什么时候用?

静态类

需要存储敏感的数据

虚方法太多,重写代价过高

老师建议:十几年经验的人:重来没用过,这是个反设计模式方案?

C#中的字符串类:system.string 就是这个玩意

接口

生命和Java一样,interface关键字来修饰,.Net 规范首字母用一个I大写表示。

posted @ 2023-04-20 09:58  咸瑜  阅读(11)  评论(0编辑  收藏  举报