当前位置: 首页 > news >正文

c#基础(一)

目录

一.创建项目

二.c#基础知识

2.1.变量

2.2数据类型、变量和对象

2.2.1数据类型和变量类型的关系

2.2.2变量类型

2.2.3常量

2.3程序框的输入输出

三、语句

3.1.声明语句

3.1.1.变量声明语句

3.1.2常量声明语句

3.2标签语句

3.3条件语句

3.3.1.条件运算符

3.3.2.if/else语句

3.3.3.switch语句

3.3.4枚举类型和switch搭配

3.3.5try语句

3.4循环语句

3.4.1for循环/while循环/do-while语句

3.4.2foreach循环

1.使用迭代器来实现遍历集合

2.使用for-each语句来实现变量集合

3.5方法

静态方法和实例方法

构造器(构造函数)

方法的重载

函数参数

值参数:

引用参数:

输出参数:

数组参数:

具名参数(本质是使用方法)

可选参数

扩展参数

数组

1.声明数组

2.定义数组

3.初始化数组

操作符

基本概念:

new操作符

typeof、default、checked、unchecked、sizeof

一元操作符

乘法运算符(*)

位移操作符(>>,<<)

关系操作符

与或非逻辑操作符

条件与,条件或

?操作符

2.10类型转换

2.10.1.隐式类型转换(直接赋值)

显式类型转换

类和对象

类怎么定义和实例化

修饰限定符及其默认值

类的成员

属性

字段(成员变量)

静态字段和实例字段

this关键字


一.创建项目

图中解决方案可以包含多个项目,在文件夹中,项目放在解决方案文件夹下,并且会生成一个和项目同级的.sln文件,这个文件是解决方案的管理文件,可以点开后再创建项目

在vs中移除项目,文件夹中并不会删除,当在vs中不小心删除可以在文件夹中找到.sln文件找回

二.c#基础知识

最基础结构:一个类型+一个静态main方法(静态不能去除

2.1.变量

如输出函数就是写在system里面的方法,要使用这个命名空间下的内容需要在上方,using System,否则只会查找本文件中有无writeLine方法

为什么需要变量并且变量要规定不同变量类型?

  • 变量:是为了分配一块空间给用户操作
  • 要规定类型是因为,在内存中只有0和1,如果不规定类型例如:56对应asc码的A,而cpu无法知道你是需要A还是56,变量的类型是给了这块内存一个标签,存放的哪种类型,准确的拿到结果
  • 在进行数据的运算时,赋值号左右的类型要相同

2.2数据类型、变量和对象

c#的数据类型分为2种五类,图中蓝色的为关键字同时也是数据类型,也就是说太常用c#把他作为关键字,当在vs中输入int 并且点击f12,可以看到int为值类型里面的结构体类型

值类型是没有实例的

引用类型的引用变量是存储实例内容地址的地址

2.2.1数据类型和变量类型的关系

int age = 25; // 变量 age 的类型是 int(变量类型),而 int 本身是数据类型
string name = "张三"; // 变量 name 的类型是 string(变量类型),string 是数据类型
  • 说 “数据类型” 时,更侧重 “数据本身的特性”(如 int 能存多大的数);
  • 说 “变量类型” 时,更侧重 “变量作为容器的特性”(如 “这个变量是 int 类型的,所以只能存整数”)

2.2.2变量类型

小内存的数据放在大内存的数据类型里会浪费空间

大内存的数据放小内存的数据类型会丢失精度

当程序运行时,数据类型放在那里?

  • 当程序运行时,程序从硬盘放到内存中,数据类型也在内存中
  • 方法放在内存的栈区,方法太多会找出栈溢出,对象放在内存的堆区,堆的内存未回收会内存泄漏,但是c#会有垃圾回收机制,当没有调用这个对象时会自动回收。
  • 局部变量也放在栈上
  • 类中的成员变量放在堆上

2.2.3常量

  • 使用const关键字
  • 常量的值不能被修改
  • 常量必须在定义时赋初值
  • 常量作为成员常量时是类型的成员,即和静态变量相同,通过类型访问
const int a = 10;

2.3程序框的输入输出

console.readline(命令框输入)、console,writeline(打印)

其中输入/输出命令框的格式都是字符串类型,因此writeline可以使用+实现字符串的拼接;readline只能用字符串接受输入数据

输出一个拼接字符串

string name = "john";
string age = "20";
Console.WriteLine("{0}is{1}", name, age);

三、语句

语句只能出现在方法体中

语句以;结尾

3.1.声明语句

3.1.1.变量声明语句

int a=100;
//声明在赋值;
int b;
b=100;
//数值使用初始化器
int [] array={1,2}

图中:a后面的就是变量初始化器,而{1,2}是数值的初始化器

3.1.2常量声明语句

const int a=100

图中:常量必须要被初始化,且值不能再发生改变.

3.2标签语句

 hell0: Console.WriteLine("hello");goto hell0;

给语句添加标签,可以在goto中直接跳转到该语句,上面代码会一直执行.

3.3条件语句

3.3.1.条件运算符

Exp1 ? Exp2 : Exp3;
Exp1是否为真,若为真则执行条件Exp2,为假则执行Exp3

3.3.2.if/else语句

int a=10;
int b=5;
if(a>b){
Console.WriteLine("hello");
}
if(a>b)
Console.WriteLine("hello");

if语句的()只能放布尔表达式

if语句只能有一条嵌入式语句,因此有时只需要一条语句时可以不加{},而{}括起来的部分,称为块语句,编译器将块语句中内容视为一条语句;

在vs中输入if点击两下Tab键直接创建代码结构

3.3.3.switch语句

using System;namespace MyApplication
{class Program{static void Main(string[] args){int day = 4;switch (day) //这里的day就是expression{case 1:Console.WriteLine("Monday");break;case 2:Console.WriteLine("Tuesday");break;case 3:Console.WriteLine("Wednesday");break;case 4:Console.WriteLine("Thursday");break;case 5:Console.WriteLine("Friday");break;case 6:Console.WriteLine("Saturday");break;case 7:Console.WriteLine("Sunday");break;}    }}
}
  • switch 语句中的 expression 必须是一个整型或枚举类型,或者是一个 class 类型,其中 class 有一个单一的转换函数将其转换为整型或枚举类型,没有浮点类型
  • case后面的数必须和 switch 中的变量具有相同的数据类型,且必须是一个常量
  • break必须每一个case都要有
  • 可以选择在增加default 作为默认
  • 并且如果两个case在逻辑上是相同范围,连起来写就行了,下面例子中如果case 8:后面写了表达式那么久必须加break,因为他变成了一个分支

3.3.4枚举类型和switch搭配

    Level level = Level.Low;switch (level){case Level.Low:break;case Level.Mid:break;case Level.High:break;default:break;}}enum Level { Low, Mid, High }

枚举类型的定义要和类的定义写在一个层面

快捷划分枚举中常量,输入switch,两下tab键,在条件中输入枚举变量level,回车自动生成.

3.3.5try语句

使用try语句尝试执行,若有错误,就不执行try语句块中内容,执行catch中内容

catch语句是分为有条件的和无条件的

下面代码若调用函数时输入不是数值形式的字符串try中内容执行时有错误,就不会改变a,b的值,并且执行catch语句,输出报错了

finally语句无论是否有错误都会执行

class jisuan
{int a = 0;int b = 0;public double Add(string num1, string num2){try{a = int.Parse(num1);b = int.Parse(num2);Console.WriteLine("a+b");}catch{Console.WriteLine("报错了");}return a + b;finally{}}
}

3.4循环语句

3.4.1for循环/while循环/do-while语句

和c语言同

3.4.2foreach循环

1.使用迭代器来实现遍历集合

如下图:可以看到我们定义的数组输入Array类(所有定义的数组都属于这个类)

  int[] array = new int[5] { 1, 2, 3,4,5 };Console.WriteLine(array.GetType().FullName);//类型名称Console.WriteLine(array is Array);//判断是否属于Array类

右键Array转到定义,所有的I开头的都是接口,所有实现了IEnumberable接口的类的实例都是可以被遍历的集合

public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable

右键IEnumberable接口,可以看到迭代器方法,所有可以被迭代的集合都能获得迭代器

 IEnumerator GetEnumerator();

使用迭代器来实现迭代,定义了一个迭代器接口类型=定义的泛型返回的迭代器,调用迭代器的MoveNext方法判断是否能向后移动(读到6就不能移动了),Reset方法回到原点,.Current属性为当前值

2.使用for-each语句来实现变量集合

for-each语句就是迭代器的简便写法

int[] array = new int[5] { 1, 2, 3,4,5 };
foreach (var item in array)
{Console.WriteLine(item);
}

3.5方法

c#中不能直接在命名空间下写函数,而必须作为某一个类的方法(如下图中的方法)

c#中方法的声明和定义是不分家的(如下图)

namespace ConsoleApp1
{class Hero{public string Name;}class Circle{//圆的面积public double Math_Circle(double r){double area=3.14*r*r;return area;}//圆柱体体积public static double Computer_cylinder(double area,double h){double Volume = area * h;return Volume;}}class Program{static void Main(string[] args){Circle C = new Circle();//调用计算面积方法double area = C.Math_Circle(2);//调用计算圆柱体体积方法double volume = Circle.Computer_cylinder(area, 3);Console.WriteLine();}}}

静态方法和实例方法

上图中的圆面积的计算方法就是实例方法,通过实例来调用,需要先把类示例化

上图中的圆柱体体积的计算方法就静态方法,通过类名来调用

构造器(构造函数)

每个声明的类都会有一个默认的构造器函数,代码如下

方法的重载

声明带有重载的方法,方法签名是由方法的名称,类型形参的个数、形参的个数、顺序、类型、种类来区分的,不包含返回类型

补充:(后面补充)

参数的种类:分为传值(普通形式),传输出(参数前加out),传引用(参数前加ref)

类型形参:泛型中内容,在函数名后<类型形参名>,可以实现在函数中定义类型形参名那种种类的参数

 class Student{public Student(string name, int age){this.name = name;this.age = age;}//函数重载public Student(string name, String age){this.name = name;this.age = int.Parse(age);}public string name;public int age;}

这个实例:是重载又是构造器

函数参数

值参数:

  • 在传递时方法体里面会创建一个副本
  • 实参和形式参数是值传递的,形式参数是实际参数的副本,两者地址不同但是存储相同数据
  • 当然:引用类型作为参数传入函数,形参和实参地址不同但是都指向相同地址,下例
static void Main(string[] args)
{Hero hero=new Hero() { Name="Superman"};Somemethod(hero);引用类型作为值传递给形式参数
}
static void Somemethod(Hero hero) { Console.WriteLine(hero.Name);}

引用参数:

使用ref关键字,不创建副本,直接将值的地址传进函数。

注意:在形参和实参位置都要加ref关键字

使用引用类型来作为引用参数也是一样的,不会创建副本,使用相同地址并且指向相同对象;

下例:值类型:y的数据也被改变,因为x和y实际是同一个地址

 static void Main(string[] args){int y = 100;refdemo(ref y);Console.WriteLine(y);//输出结果为110}static void refdemo(ref int x){x += 10;}

输出参数:

输出参数在方法体里面必须要赋值

实际参数可以只声明不赋值,值传入时被丢弃掉了

使用out关键字,相当于多一个返回值,不创建副本,和ref的区别为实际参数可以不赋值,但是在函数内必须为形式参数赋值

static void Main(string[] args)
{int y = 100;refdemo(out y);Console.WriteLine(y);
}static void refdemo(out int x)
{x = 10;//必须要赋值
}

数组参数:

params参数必须是参数列表的最后一个参数

不使用数组参数,将数组作为实际参数传入函数

 static void Main(string[] args){int[] arr = new int[5] { 1, 2, 3, 4, 5 };each(arr);}static void each( int[] arr){foreach (int i in arr){Console.WriteLine(i);}}

使用数组参数params,不需要定义一个数组,直接输入值

static void Main(string[] args)
{each(1,2,3,4,5);}static void each(params int[] arr)
{foreach (int i in arr){Console.WriteLine(i);}

具名参数(本质是使用方法)

可读性高

不受参数输入顺序限制

输入类型是键对值形式,键名要和形参一致

static void Main(string[] args)
{student(age: 20, name: "sun");
}static void student(string name,int age){Console.WriteLine("{0} is {1} years",name,age);
}

可选参数

在声明时给默认值,不输入对应参数就使用默认值

  static void Main(string[] args){student();}static void student(string name="sun",int age=18){Console.WriteLine("{0} is {1} years",name,age);}

扩展参数

扩展方法必须写在静态类中,类名约定为SomeTypeExtension

必须是形参列表中第一个参数,需要对那个类型做扩展,用this修饰这个类型

方法必须是公有的,静态的

扩展方法是增加目标类型函数功能的,下面我们为double类型添加一个保留4位小数的功能

 internal class Program{static void Main(string[] args){double x = 2.123456;double y = x.Round(3);Console.WriteLine(y);//输出结果位2.123}}
//扩展方法必须写在静态类中,类名约定为SomeTypeExtensionstatic class DoubleExtension{//方法必须是公有的,静态的public static double Round(this double num, int dec)//必须是形参列表中第一个参数,需要对那个类型做扩展,用this修饰这个类型{num = Math.Round(num, dec);return num;}}

数组

数组的写法和c语言不一致【】放在名称前类型后,顺便在这里做声明和定义的区分

并且在定义时要给他分配空间

1.声明数组

datatype[] arrayName;//这里的datatype是数据类型//声明一个int型数组int[] arr1; 

2.定义数组

(已声明的数组变量分配内存空间,并确定数组的长度(元素个数))

分配空间并且规定数组大小
arr1 = new int[3]; 

3.初始化数组

3.1动态初始化:先定义长度,再指定初始值

// 定义长度为3的int数组,并初始化元素值(首次赋值)
int[] arr3 = new int[3] { 10, 20, 30 }; 

3.2静态初始化

// 省略长度,编译器自动根据初始值个数(4个)定义长度为4,并初始化
int[] arr4 = new int[] { 1, 2, 3, 4 }; // 更简化的写法(编译器会自动补全new int[])
int[] arr5 = { 5, 6, 7 }; 

操作符

基本概念:

操作符不能脱离他关联的数据类型(整数除法和小数除法都是/,但是结果不同)

操作符优先级:

使用圆括号可以提示表达式优先级,圆括号可以嵌套

带有赋值操作符的运算顺序是先算运算符右边

除了带有赋值运算的操作符,其他都是从左到右

new操作符

new操作符:

1.创建实例,并且调用实例构造器,还能获得实例的地址,下例:new操作符创建了Hero实例,并且通过()调用了构造器,再将实例地址传给了引用变量hero;

  Hero hero1 = new Hero();  

2.调用初始化器(使用场景:只输入参数创建一个实例使用里面的一个函数,然后不使用引用参数获取他的地址,如下面例子,不使用引用参数获取他的值时,调用完成后内存被回收)

 // 传统方式:先 new 再赋值Person p1 = new Person();p1.Name = "张三";p1.Age = 25;p1.Address = "北京市";// new + 对象初始化器:一步完成创建和初始化new Person{Name = "李四",   // 初始化属性Age = 30, Gender = "男",Address = "上海市"  // 初始化公共字段}.show();

3.给匿名类型创建对象(这个类是没有创建的,因此声明类型时间用var,参数就是输入的Id这些)

 var student = new{Id = 1001,Name = "赵六",Score = 95.5};
Console.WriteLine(student.Name)

typeof、default、checked、unchecked、sizeof

typeof:获取数据类型

default:获取默认值

checked():检查到溢出会报错,可以checked{},在{}内的代码都会被检查

unchecked():不检查是否会溢出,默认设置,使用方式和checked一样

sizeof:只能获取结构体类型所占字节的大小

->操作符:间接访问,只能放在不安全上下文使用(使用unsafe并且在上方项目->项目属性->生成->勾选允许不安全上下文),在c#中指针操作,取地址操作,使用指针访问成员只能只能操作结构体类型,不能访问引用类型

struct Sport
{public String name;public int score;
}
static void Main(string[] args)
{unsafe {   Sport spo;spo.score = 100;spo.name = "football";Sport *psport = &spo;psport->score = 99;Console.WriteLine(spo.score);}}

一元操作符

*和&:指针符号和取地址符号

+、-、~操作符:可以对数值取正和负,注意:计算机中同一类型的最大最小值是不对称的,负值绝对值通常大一,因此使用+,-操作可能会导致内存溢出。

~操作符:在二进制意义上每一位取反

!:取非

++、--:和c相同,在赋值时,在变量前后结果有区别

(T)x:类型转换,看2.10类型转换详解

乘法运算符(*)

这里要注意,乘法运算符的类型是由参与运算的变量类型来决定的,如果变量有高精度会按照高精度计算

int x=10;
int y=3;
int t=3;
int result=x/y;  //结果是3
double result1=x/t  //结果是3.33333

位移操作符(>>,<<)

数据的二进制数,左位移和右位移,由于二进制的特性,不产生溢出情况:左移就是×2,右移就是/2,

位移操作符补位规则:

左移:全部补0;右移:正数补0,负数补1;

关系操作符

知识引入:

  • 编译时类型:变量声明时的类型(这里 a 和 a1 的编译时类型都是 Animal在声明时已经确定。
  • 运行时类型:变量实际指向的对象类型(a 指向 Human 对象,a1 指向 Animal 对象)运行时类型在使用new创建时已经固定了

is:检验实例是否属于类,是返回true,失败返回false

as关键字既可以检验是否是属于该类,又可以实现转换引用变量类型;

转换规则是:只有当源对象的 “实际运行时类型” 是目标类型,或目标类型的派生类型时,转换才会成功,下文中a的实际运行类型就是human,而a1的实际运行类型是animal,在使用(引用变量 as human)时只有a可以成功,返回一个等于实际类型的编译时类型,下面代码只是返回了一个human类的引用变量,而a的编译类型并没有改变.

在继承关系中,子类实例可以安全转换为父类类型(向上转型:直接子类赋值给父类,如 Human → Animal),但父类实例不能直接转换为子类类型(向下转型,如 Animal → Human),除非父类变量实际指向的是子类实例(如 a 指向 Human 实例

注意:父类变量可以指向子类实例,子类变量却无法指向父类实例

   human h = new human();if (h is human){h.thike();//使用is运算符判断这个引用变量是否为这个类的实例}human h1 = new human();if (h1 is human){h1.Eat();//使用is运算符判断子类的引用变量也可以视为父类的实例}animal a = new human();//父类变量指向子类实例animal a1 = new animal();//这种编译类型和实际类型都是animal的就不能父类转换为子类human h2=a as human;//转换仅改变引用该对象的变量的编译时类型这里是h2—— 从基类(Animal)变为子类(Human),从而解锁对 “子类独有成员” 的直接访问if (h2 != null){h2.thike();}

与或非逻辑操作符

&:按位与,是看二进制位,1和1才是真其他为假

|:按位或,有一个为真即为真

^:两位不一样才是真

条件与,条件或

||:或,操作对象和结果为布尔值

&&:与,操作对象和结果为布尔值

短路效应:当已经可以判断出结果时,后面的内容就会被跳过,如下:a>b为假,c++不会运行,c的值不变,最外层结构为A||B时,A为真则跳过判断B,最外层结构为A&&B时,A为假就会跳过A

 int a = 10;int b = 20;int c = 10;if (a > b && c++ > 10){}Console.WriteLine(c);

?操作符

举例说明:

   int? a = null;var x = a?? 10;

上面代码

int ?a=null含义为定义一个可空的int类型元素a=null(int?是语法糖,全写为 Nullable<int>)

??是空合并运算符,若a为空返回10,若不为空返回a的值

2.10类型转换

2.10.1.隐式类型转换(直接赋值)

不丢失精度的类型转换:低精度向高精度转换

子类向父类的类型转换:直接把子类引用类型赋值给父类的引用类型,注意:转换后的父类引用类型只能访问他自己有的成员方法和成员变量

        static void Main(string[] args){   human h = new human();animal a = h;
//直接将h赋值给父类的引用类型,注意,父类只能调用他自己有的方法和属性a.Eat();}}class animal
{public void Eat(){Console.WriteLine("animal is eating");}
}class human : animal {public void thike() {Console.WriteLine("human is thiking");}}

显式类型转换

使用类型转换关键字,一般是同类型数据高精度向低精度转换

double x = 3.14159;
int y = (int)x; // 显式转换:double → int(小数部分被截断,y=3)

特别的是char和整数之间的转换,但是因为字符对应码表的原因,可以相互转换

char c = 'A';
int code = (int)c; // 结果:65('A'的Unicode编码)

注意:这种类型转换是可能造成溢出的,而double转换为int类型不显示小数部分是截断因为int就是表示的整数,不是一个概念

convert类:直接在编译器.来查看有那些方法

Tostring方法:这个方法是写在object类中的在上文数据类型中可以看到,所有的数据类型都是他的派生,因此都有Tostring方法,Tostring是实例方法,通过实例调用

  int x = 20;x.ToString();

Parse方法:将字符串类型转换为目标类型,Parse是静态方法,通过类名称调用,注意:只能转换格式正确的,如:123转换为int类型

// int.Parse:字符串转整数
string intStr = "123";
int num = int.Parse(intStr); // 转换成功,num = 123// double.Parse:字符串转双精度浮点数
string doubleStr = "3.1415";
double pi = double.Parse(doubleStr); // 转换成功,pi = 3.1415// decimal.Parse:字符串转高精度小数(适合金额)
string decimalStr = "199.99";
decimal price = decimal.Parse(decimalStr); // 转换成功,price = 199.99

类和对象

类怎么定义和实例化

不调用实例构造器方式

 class Hero{public string Name;}class Program{static void Main(string[] args){//这里的hero1叫引用变量Hero hero1 = new Hero();        hero1.Name = "Superman";Console.WriteLine("Hello, " + hero1.Name + "!");}}

调用实例构造器方式

static void Main(string[] args)
{Hero hero=new Hero() { Name="Superman"};
}class Hero
{private string name;public string Name{get { return name; }set { name = value; }}}

修饰限定符及其默认值

C# 封装根据具体的需要,设置使用者的访问权限,并通过 访问修饰符 来实现。

一个 访问修饰符 定义了一个类成员的范围和可见性。C# 支持的访问修饰符如下所示:

  • public:所有对象都可以访问;
  • private:只在类的内部可以访问,即使是类的实例也不能访问它的私有成员;
  • protected:只有该类对象及其子类对象可以访问
  • internal:同一个程序集的对象可以访问;
  • protected internal:访问限于当前程序集或派生自包含类的类型。

  • 顶层类型指直接定义在 namespace 中的类、结构体、接口、枚举、委托等,其默认访问修饰符为 internal
  • 嵌套类型指定义在类、结构体内部的类型(如类中的嵌套类),其默认访问修饰符为 private
  • 类(class)和结构体(struct)的成员(字段、方法、属性、事件、构造函数等),默认访问修饰符为 private

类的成员

属性

作用:是为了避免数据污染,属性是字段的包装器。

类属性是有默认值的,而写在progress类中的mian方法里面的变量称为本地变量,本地变量是没有默认值的

属性的完整写法

快捷键写法:输入propfull(prop是property的缩写),按两下tab键,使用tab键选择给我们修改的地方,快速生成

注意:

属性的set和get是没有();

调用set方法时value是不需要自己定义的,等于给他赋的值

  private int age;public int Age{get{return this.age;}set{if (value >= 0 && value <= 120){this.age = value;}else{throw new Exception("age value is error");}}}

字段(成员变量)

静态字段和实例字段

静态字段用来描述一个类型共有的属性,实例字段描述一个实例单独的属性

静态字段和类同级,无论多少个实例,一个类中同名静态字段只有一个

静态字段通过类名调用,实例字段通过实例调用

 static void Main(string[] args){Student stu=new Student();stu.name = "John";stu.age = 20;Student stu2 = new Student();stu2.name = "Mary";stu2.age = 22;double average_age = Student.average_age=(stu.age+stu2.age)/ (double)2;Console.WriteLine(average_age);}class Student{public static double average_age;public string name;public int age;}

this关键字

  • this 只能在实例成员(实例方法、实例属性、实例构造函数)中使用,静态成员(静态方法、静态构造函数)中不能使用 this(因为静态成员属于类,不属于某个实例)
  • this 的核心是 “当前对象的引用”,就是指向当前对象的指针,它的主要作用是:区分同名成员与局部变量(加this的是成员)、传递当前对象、调用其他构造函数、定义扩展方法。
  • this 写在类的定义中,是 **“提前声明” 了一种 “对当前实例的引用方式”**,但此时还没有具体的实例,所以它是 “抽象的占位符”。
  • 当通过 new 创建实例后(比如 zhangsan = new Person()),这个实例在内存中存在了。此时调用实例的方法(zhangsan.SayHello()),this 就会动态绑定到这个具体实例zhangsan),所以 this.Name 才能正确拿到 “张三

文章转载自:

http://OLBlQ4FK.qfwfj.cn
http://O2emzdy0.qfwfj.cn
http://6HAFA6nd.qfwfj.cn
http://GiRtUQ1u.qfwfj.cn
http://CROELUTS.qfwfj.cn
http://hUg8YmNq.qfwfj.cn
http://F5Di48Nv.qfwfj.cn
http://LuI06qaa.qfwfj.cn
http://sWAxncbj.qfwfj.cn
http://ODnFybbZ.qfwfj.cn
http://hOlIvOBs.qfwfj.cn
http://XUri1WcR.qfwfj.cn
http://kA23SBs9.qfwfj.cn
http://TU8zjl1K.qfwfj.cn
http://J3l5Ia1W.qfwfj.cn
http://IwqnGkR8.qfwfj.cn
http://JiGxogW3.qfwfj.cn
http://tiBKVHGi.qfwfj.cn
http://pgxAFvBl.qfwfj.cn
http://FhPPg2oC.qfwfj.cn
http://DHLiHle8.qfwfj.cn
http://sjUvnTix.qfwfj.cn
http://NkbPOVFe.qfwfj.cn
http://X8SJly6u.qfwfj.cn
http://hRUWK47X.qfwfj.cn
http://psJlrs2Z.qfwfj.cn
http://3Ji0vsoc.qfwfj.cn
http://r3rTww0z.qfwfj.cn
http://Ykcc3zA7.qfwfj.cn
http://ijIwBIUH.qfwfj.cn
http://www.dtcms.com/a/377774.html

相关文章:

  • VMware Workstation 不可恢复错误:(vcpu-1) Exception 0xc0000005 解决方案
  • IndexTTS2.0_ 情感表达与时长可控的自回归零样本语音合成突破
  • Git提交文件提取工具:一键将特定提交的文件导出到指定目录
  • 中间件漏洞详解
  • TC_Motion多轴运动-PID调节
  • Java 学习笔记(进阶篇3)
  • 金蝶云星空 调价表取历史价格
  • TwinCAT3人机界面1
  • C#语言入门详解(18)传值、输出、引用、数组、具名、可选参数、扩展方法
  • 【C++世界之string模拟实现】
  • 打工人日报#20250910
  • LeetCode100-206反转链表
  • function-call怎么训练的,预料如何构建
  • OpenLayers数据源集成 -- 章节四:矢量格式图层详解
  • 220V供电遥测终端 220V供电测控终端 选型
  • 【LLM】Transformer注意力机制全解析:MHA到MLA
  • 三十六、案例-文件上传-阿里云OSS-集成
  • 网编.hw.9.10
  • 4215kg轻型载货汽车变速器设计cad+设计说明书
  • Python数据可视化科技图表绘制系列教程(七)
  • 【 VMware Workstation 提示“虚拟机已在使用”怎么办?一篇文章彻底解决!】
  • WebSocket网络编程深度实践:从协议原理到生产级应用
  • 数字健康新图景:AI健康小屋如何重塑我们的健康生活
  • ⚡ Linux sed 命令全面详解(包括参数、指令、模式空间、保持空间)
  • Codeforces Round 1049 (Div. 2) D题题解记录
  • 视频分类标注工具
  • 【学习】vue计算属性
  • Torch 安装
  • 如何使用 DeepSeek 帮助自己的工作?的技术文章大纲
  • Object.values(allImages).forEach(src => { }