温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

c#开发之五---c#语言基础

发布时间:2020-06-18 01:24:02 来源:网络 阅读:1267 作者:kuang_hp 栏目:编程语言

第一部分  重点基础

 

  • 基础部分

 

1、  快捷键

Ctrl+e+d  快速对齐代码

Ctrl+S    保存

Ctrl+z    撤销

Ctrl+k+c  注释代码

Ctrl+k+u 取消注释代码

#region  #endregion 折叠代码

Ctrl+鼠标滚动  放大,缩小界面

双击tab键,自动出现console.writeline();

ctrl+.  或者  shift+alt+F10 导入命名空间(using)(当关键字下面出现提示的时候)

ctrl+r+e : 自动封装属性

2、  数据类型

 

Int       整型

Double   浮点型,可带小数

Float     浮点型

String     字符串 ,加双引号

Char      单个字符,加单引号

Decimal   金钱,钱数后要加”m”

 

3、“+”号

有一边有字符类型,起到连接的作用。

两边都是数字,就是相加。

 

3、  占位符”{}”

用在输出方法中。

例:

String name=”

Int age=30;

Console.Writeline(我叫{0},我今年{1}name,age);

 

4、  输入、输出

Consoe.writeline(“请输入您的姓名”)//提示输入姓名,把这行字显示到显示屏上

String name=Consle.readline();       //定义一个name字符串变量,把输入的值存入变量

Consoe.writeline(“您的姓名是{0}”,name)

Console.readkey();

 

 

5、  转义符\+特殊字符组成有特殊意义的字符\n   换行

\r\n windows系统的换行

\t   TAB键的空格

\”   双引号

\b   表示一个退格符

\\   表示右斜杠。

 

6@

取消\在字符中的转义作用,例   sting str=@”f:\file\rmvb\1.rmvb”;一般在有路径的情况下加@符号,取消右斜杠的转义作用。

 

@还可以保留原格式输出

 

7、  转换

(1)隐式转换  (小的转换成大的,可以自动隐式转换,如int转换成double double就不能隐式转换成int)

Int a=3

Double b=3.14

double c=a*b  //隐式把int 的变量a,转换成double类型。

 

2)显示转换(大的转成小的,就必须显式转换,必须兼容)

 

Int a=3

 

Double b=3.14

 

Int c=a*(int) b  //显式的把double转换成int类型

 

 

3convert 转换(类型不兼容的情况下用,但也有限制,如不能把字符abc,转换成doubleint)

 

String s=”123”;

Double d=Convert.ToDouble(s);//string类型的变量转换成double类型,赋值给变量d.

Int c=Convert.ToInt32(s);     //string类型的变量转换成int类型,赋值给变量c.

 

 

8++--

 

1++

例:

Int a=10

 

Int b=10+a++;

上面这一个语句,可以用下面两条语句表达:

{int b=10+a;  //此时b=20

a++;       //此时a=11,  a++a=a+1

}          

 

 

 

例:

Int a=10

 

Int b=10+ ++a;

上面这一个语句,可以用下面两条语句表达:

{

a++;       //此时a=11,  a++a=a+1

 

int b=10+a; //此时b=21

}          

 

++在前,即先自身加1,再参加运算。

++在后,即先用原值参加运算,然后自身再加1.

 

 

9、  关系表达式和布尔关型

==

>=

<=

!=

 

关系运算符连接的表达式,称之为关系表达式。关系表达式的结果只有对和错两种。用布尔类型来反应。

 

例:

 

Bool b=38>39;  //因为38小于39,所以这是b的值为False.

 

 

10、             逻辑运算符

一般两边是布尔类型或关系表达式。

&& 

||  

  

 

11、             复合赋值运算符

 

+=

-+

*=

/=

%=

11、调试

1F11单步调试:从头至尾一行一行的调试。

2F10  方法调试

3    断点调试,先在想设断点的代码左边点击鼠标,再点击启动,然后再按F11一步一步调试。

可以在调试,窗口中,调出监视窗口来监视变量

 

 

  • 语句

1if else

 

(1)    if

if(判断)  //判断为真执行下面的语句。判断为真后,只执行一遍下面的语句,不循环。

{  }

 

2if else

If(判断)   //判断为真执行下面的语句,为假则执行ELSE里的语句。

{   }

Else

 

{  }

注意,else语句匹配离他最近的if语句。

3if   else-if   //如果第一个if判断为真,则执行下面大括号的语句,然后跳出,不进行后面的所有判断。

If(判断)   //主要用来处理多条件区间性判断。多条件固定值判断一般用switch 

{   }

Else if (判断)

 

{  }

Else if (判断)

{  }

…….

Else

{  }

2switch

switch(变量或表达式的值)  //先算出变量或表达式的值,然后用算出的值与下面catch语句里的值进行匹配,匹配成功,就执行后面的代码,遇到break语句,跳出switch语句。如果不成功继续与下面的catch里的值进行匹配,直到匹配为止,如果都不匹配,则看是否有default语句,有的话就执行default语句中的代码,然后跳出switch

 

catch 1:要执行的代码

break;

catch 2:要执行的代码

break;

catch 3:要执行的代码

break;

 

……

default:要执行的代码     //都不匹配就执行default里的代码

break;

3、  while

 

1while

while(循环条件)  //当判断循环条件成立时,则执行下面的循环体,执行完循环体中的代码后,再进行循环条件判断,如成立,继续执行循环体,如不成立则跳出while。循环条件一般为布尔类型或表达式。

 

{ 循环体

}

 

 

2do while

Do

 

{ 循环体}

 

While(循环条件)  //先执行一遍循环体,再进行循环条件的判断,判断为真继续执行循环体,否则跳出do while循环。

 

4、  for  (已经知道循环次数时用for

for (表达式1,表达式2,表达式3)

{循环体}

 

表达式1为声明循环变量,计录循环次数。如,int i=0

表达式2为循环条件,i<10

表达式3为改变循环条件的代码,使循环条件终有不成立的时候,如i++

 

5、  breakcontinue

 

(1)    break

跳出当前循环体,不再循环。一般不单独出现,和if一起用,当满足某种条件是跳出循环体。

 

2continue

跳出本轮循环,重新检测循环条件,继续下一轮循环。一般也和if一起用。

 

 

Breakcontunue的区别好比跑步,如果要跑100圈,当跑到10圈遇到break时,直接不跑了,干其他没干完的事去了。而遇到continue时,你只是临时下场,这一圈不跑了,然后再上场接下来跑余下的90圈。

三、异常

1try  catch finally

 

try              //捕捉异常,包含被异常保护的代码

{   }

 

Catch (可带异常变量,匹配执行某类型的异常)        //如果出现异常,将执行的代码

{   }

Catch (可带异常变量,匹配执行某类型的异常)        //如果出现异常,将执行的代码

{   }

……

Finally           //不管出不出现异常,都将执行的代码

 

{   }

 

 

2throw

 

  • 数据类型详解

(一)  数据类型简介

浮点型:

Float

Double

Decimal

 

整数型:

Int

Uint

Long

Short

……..

 

非数值型:

Bool 布尔

Char 单个字符

 

用户自定义类型:

class

结构 struct

枚举 enum

委托 delegate

接口 interface

数组 arry

 

()数据类型详解

 

1、  常量   用在不更改的数据上面。如超市统一的打折率。

Const 变量类型  变量名=值;  //常量声明时必须赋值,且赋值后就不能再更改。

Const int number=50;          //值就一直为50,不能重新赋值。

Number=40 //这就会出错。不能改。

 

2、  枚举

1)语法:

[public] enum 枚举名:枚举值类型  (一般枚举值类型是省略的)

{

         1,                //默认为值1=0;

         2,                //默认为值2=1;

         3,                //如果此处值3=10;,则值4=11,以此类推。

         ........

}

public:访问修饰符。公开的公共的,哪都可以访问。

enum:关键字,声明枚举的关键字

枚举名:要符合Pascal命名规范

枚举是值类型,和Int等类似。

枚举只能存储同一类型的数据。

 

2)枚举的转换

 

Int类型可以和枚举互转。

枚举可以转换成字符串类型,用tostring()方法。

字符串类型转换成枚举类型时用parse()方法。

 

 

3、  结构

语法:

[public] struct 结构名

{

         成员;//字段,默认是Private类型,要想对外可访问,要加Public

}

变量在程序运行期间只能存储一个值,而字段可以存储多个值。

 

4、  数组

数组类型[] 数组名=new 数组类型[数组长度];

二维或三维就是增加[]

int [][] number=new int[2][3];//二维数组,两列三行的数组,实例化是一定要指定长度,或直接初始化。

 

***数组的长度一旦固定了,就不能再被改变了

 

5、  事件

 

  • 方法(函数)就是将一堆代码进行重用的一种机制。

1、  方法的语法:

函数的语法:

[public] static 返回值类型 方法名([参数列表])

{

         方法体;

}

public:访问修饰符,公开的,公共的,哪都可以访问。

static:静态的

返回值类型:如果不需要写返回值,写void

方法名:Pascal 每个单词的首字母都大些。其余字母小写

参数列表:完成这个方法所必须要提供给这个方法的条件。如果没有参数,小括号也不能省略。

 

方法写好后,如果想要被执行,必须要在Main()函数中调用。

2、  方法的调用与传递

类名.方法名([参数]);

在某些情况下,类名是可以省略的,如果你写的方法跟Main()函数同在一个类中,这个时候,

类名可以省略。

参数传递方法有:

值传递

引用传递

 

当方法声明有返回值类型时,方法体中一定要用return返回一个同类型的值。

3、  Ref

引用参数,传输的是变量的地址值,所以不管是调用代码中,还是方法体内的更改,值变量值都会发生改变。

reft参数一定要在方法外赋值,方法内可以不用赋值。如在调用代码中先赋值。

可以把值传进方法,也可以把值从方法中传出来。

 

staticvoid Main(string[] args)

        {

            double salary = 5000;

            JiangJin(ref salary);//虽然没有返回值,但代码中调用jiangjin方法后,salary的值变成了5500.

            Console.WriteLine(salary);//此处值为5500

            Console.ReadKey();

        }

 

        publicstaticvoid JiangJin(refdouble s)//此时是参数S的地址值,所以此方法中如果改变了参数的值,在调用代码中也会改变。所以此处也没有返回值。

        {

            s += 500;

        }

      

 

4、  Out

 

传输多余的变量值到调用代码中,只能把方法内的数据传出去,不能传进来。

一般用在一个方法中需要返回多个数据类型的值时。如既需要string类型,也需要返回int类型时。

调用的方法中有out关键时,调用代码中也需要加上out关键字

out参数一定要在方法内初始化赋值。

 

{          Console.WriteLine("请输入用户名");

            string userName = Console.ReadLine();

            Console.WriteLine("请输入密码");

            string userPwd = Console.ReadLine();

            string msg1;  //此处可以赋初值也可以不赋初值,因为此参数是out实参,out实参在方法体中会赋初值,且会把最终返回值到此处。且实参名不必和形参名一样,但实参一定要声明不可省略。

            bool b = IsLogin(userName, userPwd, out msg1);//调用IsLogin函数,传递实参到方法的形参中去。此处调用方法的返回值是bool类型,而多余返回值为msg1string类型。且此处一定要加上out关键字。

            Console.WriteLine("登陆结果{0}",b);

            Console.WriteLine("登陆信息{0}",msg1);

            Console.ReadKey();

        }

 

        ///<summary>

        ///判断登陆是否成功

        ///</summary>

        ///<param name="name">用户名</param>

        ///<param name="pwd">密码</param>

        ///<param name="msg">多余返回的登陆信息</param>

        ///<returns>返回登陆结果</returns>

        publicstaticbool IsLogin(string name, string pwd, outstring msg)//此方法的返回值为bool类型,同时传递两个参数值和一个多余参数值过来,返回时,会返回一个bool类型的方法返回值,还会多余返回一个string类型的返回值。且多余返回形参前面一定要加Out关键值。

        {

            if (name == "admin" && pwd == "888888")

            {

                msg = "登陆成功";                           //out参数赋值。

                returntrue;

            }

            elseif (name == "admin")

            {

                msg = "密码错误";                         /out参数赋值。

 

                returnfalse;

            }

            elseif (pwd == "888888")

            {

                msg = "用户名错误";

                returnfalse;

            }

            else

            {

                msg = "未知错误";

                returnfalse;

            }

5、  Pars

 

 

6、  方法重载

概念:方法的重载指的就是方法的名称相同给,但是参数不同。

参数不同,分为两种情况

1)、如果参数的个数相同,那么参数的类型就不能相同。

2)、如果参数的类型相同,那么参数的个数就不能相同。

***方法的重载跟返回值没有关系,即如果仅仅返回值不同,构成不了重载。

 

7、  方法的递归

自已调用自已。

要考虑到入口,再考虑到出口。即一定要考虑到什么时候停止调用自已。不然就死循环了。

你调用多少次递归,就要有多少次返回。如你画圈,调用递归你画了十层圈,你不能通过return就立即跳出十层圈,而是得一层一层的跳,要跳十次才能跳出。

 

 

六、类

1、  基本语法

[public] [static]class 类名

{

         字段;       //在外面叫变量,在类里叫字段。在类里如果不加修饰符,默认为private

         属性;       //实质上就是getset方法,主要是为了保护字段。

         方法;       //实现方法。

构造函数;   //主要是初始化类,如果不定义构造函数,系统会自动生成一个默认的。

析构函数;   //释放类的资源和空间。

}

 

创建类的对象过程,叫类的实例化。

 

2、  修饰符

Public:公开的。类里的成员可访问、类外的成员可以通过类对象访问、派生类的成员可以直接访问。

 Private:私有的,只在当前类内部访问。只有类里的成员可以访问,就算是本类的实例化对象也不能访问。

Protected:保护的,只有当前类内部和派生类(子类)可以访问,孙子辈也可访问。。

Internal:当前程序集中访问。(当前项目中访问),在同一项目中,和public权限是一样的。修饰类时,不加修饰符时,Internal是默认修饰符。

Protected internal:protected+internal的权限。

 

只有public intenal可修饰类类型,如: public class test(){};

子类的访问权限不能高于基类,会暴露父类的成员。

 

3、属性(在字段下按快捷键ctrl+r+e快速实现属性。)

Set Get的应用

一般面向对象编程语言都要求成员变量不能直接暴露给外部访问,如下:
public class A
{
    public int Age;   //
这是不好的,待会有程序员可能把-1赋给Age
}
为了防止乱赋值,C#设计了一个属性机制,要求把成员变量设为私有,在通过属性来控制成员变量的读写,如下:
public class B
{
    private int age;  //
私有成员字段
    public int Age    // age
的属性,字段的属性名一般是把字段名首字母大写。此声明等同于public int Age(int value)value是隐含参数,只是不写出来。
    {
        get{ return age; }  //
读取器,当代码中调用属性时,启动get方法,在get方法中也可以写判断语句,赋值等,和set一样。在get里有判断的话,判断类中的字段。
        set{                //
写入器,当代码中给属性赋值时,调用set方法。在set中就判断value
            if(value>0)
              age = value;   //value
是准备写入的值
        }
    }
}
这样Age就像保安一样,挡在age的前面。访问age的时候需要通过Age许可,如下:
B b = new B();
b.Age = -1;  //
这是不行的,-1被带入valuevalue<0,判断不成立
b.Age = 10;  //
这是可行的,当给属性赋值时调用属性的set方法。把10传到Age属性的value隐形参数中,并且调用set方法。

Consloe.WriteLine(“请输入年龄{0}”,b.Age)//此时调用Age属性中的get方法,调用时只调用属性,不会直接调用私有化的字段

 

属性中setget不是必须都需要的,但必须有其中一个。如果只有set方法就是只写属性,如果只有get方法,就是只读属性。

属性的作用就是保护字段、对字段的赋值和取值进行限定。

属性的本质就是两个方法,一个叫get()一个叫set()

既有get()也有set()我们诚之为可读可写属性。

只有get()没有set()我们称之为只读属性

没有get()只有set()我们称之为只写属性

 

4、静态static和非静态

内存的区域:

栈:存储值类型,如Intenum,struct

:存储引用类型,如string,interface,class ,arrydynamic,object等。即在栈里只有一个指针,指针指向堆里的地址,所有的数据都存在堆里。

静态存储区域:存储静态类型。静态存储区域所有项目成员都可以访问,所以静态成员在整个项目中资源共享。且静态成员在代码编译时就分配了内存空间,而非静态成员只有在编译后才分配内存空间,所以静态成员无法调用非静态成员,因为非静成员有可能当时还没有生成。且只有当程序完成后才会释放空间。所以静态类型占用内存。

一般在你想做一个工具类时,即大家都会经常用到的类时,才会写成静态类。

 

非静态类中:

1)、在非静态类中,既可以有实例成员,也可以有静态成员。

2)、在调用实例成员的时候,需要使用对象名.实例成员;

    在调用静态成员的时候,需要使用类名.静态成员名;

总结:静态成员必须使用类名去调用,而实例成员使用对象名调用。

           静态函数中,只能访问静态成员,不允许访问实例成员。

     实例函数中,既可以使用静态成员,也可以使用实例成员。

   

静态类中:

 

只能有静态成员,不能出现实例成员。

静态类不能被实例化。

 

5、构造函数

构造函数的作用是初始化类。

构造函数不能有返回值,连void也不行。

构造函数名和类名一样。

静态构造函数:

主要为类的静态字段进行初始化

一个类只能有一个静态构造函数,且不得带参数,不能有访问修饰符,如public

 

6、析构函数

 

7this

表示当前类的对象,类不占内存,但对象占内存。

只能用在:实例构造函数、实例方法以及属性和索引器的实例访问器。

 

8partial部分类

在一个类中可以写两个完全相同的类,并且类与类之间的所有数据都可以共享,你就可以把他当成一个类,只是有两个地方。类名前加上关键字partial

9sealed密封类

不能够被其他类继承,但是可以继承于其他类。

Public sealed class preosn()

{};

 

 

七、继承

1、子类继承的内容:

(1)子类继承了父类的public字段、属性和方法,但是子类并没有继承父类的私有字段。

(2)子类不继承父类的构造函数,但调用父类的无参构造函数,以创建父类对象,以使子类可能使用父类中的成员。所以,如果在父类中重新写了一个有参数的构造函数之后,那个无参数的就被干掉了,子类就调用不到了,所以子类会报错。

解决办法:

在父类中重新写一个无参数的构造函数。

在子类中显示的调用父类的构造函数,使用关键字:base()

2、继承的特性

继承的单根性,一个子类只能有一个父类。

继承的传递性,从父类继承的内容,可以被自已的子类继承。

3、  object是所有类的基类

 

4、  语法:

 

Public class 类名:父类名   //注意,这里的修饰符要比父类的一致,或比父类的权限小,不能比父类的权限大。

 

5、  如果子类有与父类一样的方法,将隐藏父类的方法,即把父类覆盖了。

6、  要显示的隐藏父类中的方法,可以在子类的方法名前加关键字new.

7、子类的实例化对象可以赋值给父类的实例化对象。但父类的不能赋值给子类。

 

八、多态性

 

 

1、  虚函数

(1)    语法

在基类中把虚函数加上关键字virtual,在子类中在函数前加上关键字override

例:

Public class animal

{

Public virtual void test ()   //基类中声明时加上关键字,声明成虚函数。

{

Console.writeline(“我是父类的”)

}

}

 

Public class cat:animal

{

  Publicoverride void test()//子类中加上override重写虚函数。这里也可以不加,但不加的话就要加上关键字new,把父类的函数隐藏。即子类可以重写父类的虚方法,也可以不重写。

 

{

Console.writeline(“我是子类的”)

}   

 

 

Animal aa=new cat();   //把子类对象赋值给父类对象。

 

aa.test();  //调用子类中的test方法。执行过程如下:

 

程序执行到此处,跳转到父类的test函数上,但不执行父类的函数体,接着就跳到子类cat test函数上,并且执行函数体。  即此处aa对象赋的是哪个类的对象值,就执行哪个类中的虚函数。

 

2)虚函数的作用

子类继承了虚函数后,子类可以重写虚函数,也可以不重写,实现多态性。

当父类的虚函数的实现也有作用时,用虚函数。子类继承了虚函数后重写虚函数。

虚函数就是用

3)注意事项

子类中的虚函数要和父类的一致,即子类中的虚函数和父类中虚函数的返回值,类型,参数都要一致。

 

 

2、  抽象类

(1)    语法:

父类:

public Abstract  class animal             //在抽象类前面加上abstract关键字。

{

Public Abstract void test(int i);         // 抽象方法前面也加上abstract关键字。修饰符不能是private。抽象方法是不能有方法体的,连大括号都不能有。所有的抽象成员在子类中必须被重写。

Public void sum()                 //抽象类中允许有非抽象方法和非抽象字段,属性。

{   }

}

Animal dog=new animal();       //这是错误的,抽象类是不能被实例化的。

 

子类:

 

Public class cat:animal

{

Public Override void test(int j)       //子类中用override重写抽象方法,且父类中的所有抽象成员必须在子类中重写。

 {   }

public Override num()            //这种写法是错的,抽象方法只能出现在抽象类中。除非子类也是抽象类。

{   }          

}

(2)    注意事项:

1.抽象成员必须标记为abstract,并且不能有任何实现。

2.抽象成员必须在抽象类中。

3.抽象类不能被实例化

 

4.子类继承抽象类后,必须把父类中的所有抽象成员都重写。

(除非子类也是一个抽象类,则可以不重写)

 

5.抽象成员的访问修饰符不能是private

6.在抽象类中可以包含实例成员。

并且抽象类的实例成员可以不被子类实现

 

7.抽象类是有构造函数的。虽然不能被实例化。

8、子类重写父类的虚函数时,必须与父类一致,即返回值类型,参数及参数类型都要保持一致。

--------------------------------------------------------------------------------------------------------------------------------

如果父类中的方法有默认的实现,并且父类需要被实例化,这时可以考虑将父类定义成一个普通类,用虚方法来实现多态。

 

如果父类中的方法没有默认实现,父类也不需要被实例化,则可以将该类定义为抽象类。

 

 

 

3、  接口

 

(1)      语法:

 

Public interface ikoulan

{

Void koulan();   //接口中的函数和抽象函数一样,不能有方法体。继承接口的子类,必须实现接口中的所有成员。接口不能被实例化。前面不能加修饰符,默认是public.

String daqui(); //接口中只能有方法、属性、索引器、事件成员,不能有构造函数和字段。

}

 

 

Public class prson:ikoulan

{

Public void koulan()  //这是prson类已有的函数。当人类里面已有一个koulan函数时,就要另外显示的实现接口函数,在函数前加上接口名。

{

}

Void ikoulan:koulan()                       //一定要实现接口中的成员。因为子类中已有相同名的函数名,所以在这里显示的加上接口名。如没有得复不用加接口名。

{

Console.writeline(“高个可以扣篮”);

}

 

}

 

 

main函数中:

Ikoulan test=new prson();  //接口不可以实例化,但是可以把子类的对像赋值给接口对象。

 

(2)      用法

当想多继承时,就需要用到接口,因为类是单继承的,只能用接口来实现多继承。

接口就是一种规范,能力。

接口与接口之间可以继承,并且可以多继承,即一个接口可以继承多个接口。

接口并不能去继承一个类,而类可以继承接口  (接口只能继承于接口,而类既可以继承接口,也可以继承类)

当几个类提取不出来一个父类,但有一个共同的行为时,用接口。

当几个类能提取出一个父类,且有这几个子类都必须执行的方法,但是不知道这方法怎么实现时,就用抽象类,实现多态性。

当几个类能提取出一个父类,且有这几个子类都必须执行的方法,且知道怎么实现这个方法,还想实例化父类时,就用虚函数实现多态性。

 

(3)      注意事项。

 

八、集合与泛型

很多数据的集合,和数组类似。

数组长度不可变,类型单一。

集合的长度可以任意改变,类型随便。

1、  Arraylist

方法:

(1)      ADD方法:把单个元素添加到集合中。

 ArrayList list=new ArrayList();

  List.Add(1);          //添加整型数据到List集合

 List.Add(“张三”);     //添加字符串到List集合

 List.Add(new int[]{1,2,3,4,5}); //添加数组到List集合。此时如果遍历List时,会显示数组的命名空间名字,而不会显示数组中的元素。要解决这个问题,要用addrange方法。

      

(2)    AddRange方法用于添加一批元素到当前列表的末尾

List.AddRange(new int[]{1,2,3,4,5}); //添加数组到List集合。

List.AddRange(list);           //把自已添加到自已的集合里面。

(3)    Remove方法用于删除单个元素,通过元素本身的引用来删除

List.Remove(“张三”);     //写谁就删谁。

(4)    RemoveAt方法用于删除一个元素,通过索引值来删除,即下标。
List.RemoveAt(0);      //
会删除List.Add(1)中的1,他是第List中的第一个元素。

(5)    RemoveRange用于删除一批元素,通过指定开始的索引和删除的数量来删除

List.RemoveRange(03);  //删除list中第1个元素开始后的三个元素。

(6)    Insert在指定的索引位置插入元素,列表后面的元素依次往后移动

List.Inset3,“李四”); //在第4个元素后插入字符串李四。

(7)    InsertRange在指定的索引位置插入一批元素(在集合中插入集合),列表后面的元素依次往后移动

List.InsetRange(1,new string[]{“王五”,赵六”,”李七”}); //在第2个元素后插入字符串数组。

(8)    Clear方法用于清除现有所有的元素

(9)    Contains方法用来查找某个对象在不在列表之中,即判断集合中是否包含指定的元素。

Bool a=list.contains(“李七”);   是否包含李七,包含为1,不包含为0,即假。

(10)  sort升序排列集合,但要求集合中的元素的类型基本一致才可行。

(11)  count:表示集合中实际包含的元素的个数

(12)  capacity:集合中可以包含的元素的个数。当实际包含的元素个数超过可包含的元素个数时,集合会向内存中申请多开辟一倍的空间来保证集合的长度一直够用。

13)遍历arraylist集合:

For(i=0;i<list.count;i++)   //list.count表示集合的长度

{

Console.writeline(list[i]);

}

2、hashtable  键值对集合,类似于字典,根据键找到值,键和值一一对应。

(1)  方法:

Hashtable ht=new hashtable();

Ht.Add(1,”张三”);       //添加值到集合中

Ht.Add(2,”李四”);

Ht.Add(false,”错误”);  //键是false

Ht[true]=”正确”;      //也可以通过赋值方法来添加元素到集合中。

Console.writeline(ht[1]);  //打印出键为1的值,会显示出 张三

Ht.clear();            //清除所有元素

Ht.remove(3);        //根据键来清除单个元素。

 2)遍历集合

Foreach(var item in htlist)      //foreach循环来遍历hashtable集合。

 

Foreach(var item in ht.keys)  //keys属性是指hashtable集合的键,即遍历整个集合的键

{

Console.writeline(“键是{0},值是{1}”item,ht[item]);  //同时显示键和值。Item代表了键,而ht[item]代表了每个键对应的值。

}

3)键值对集合中键必须唯一

键值对集合中,键必须是唯一的,值可以重复。所以添加元素到集合中时,先判断键是否已存在。

If(ht.containsky(“true”))   //如果ht集合中已包含键true

 

3、  list泛型集合

1)泛型集合的要点:

要指定集合的类型,集合中的元素都要是这个类型的。

arraylist的不同之处就是要指定元素的类型,其他方法基本一样。

List泛型集合可以转换成数组,数组也可以转换成集合。

2)建立list集合对象:

List<int> list=new list <int>();   //声明一个List集合,<>号中指定元素的类型。

 

3)集合转数组和数组转集合

   Int[] num=List.toarray();    //toarray方法把list集合转换成数组,转换成什么类型的数组取决于你是什么类型的集合。

 

   Char[]chs =new char[]{‘a’,’b’,’c’};

   List<char>listchar=chs.ToList();   //ToList方法把数组转换成集合。

 

4、  字典集合

(1)    字典集合的要点:

hashtable集合使用方法完全一致,只是键和值指定了类型

键也必须是唯一的

 

2)建立字典集合对象

Dictionary<int,string>dic=newDictionary<int,string>();

 

(3)两种遍历方法

方法一:

Foreach(var item in dic.keys)

{

Console.wirteline(“键是{0},值是{1}”,item,dic[item]);

}

     方法二:

   Foreach(keyValuePair<int,string>kv in dic)   //keyvaluepair表示键值对,既表示键也表示值,所以这种方法可以让键和值一起显示。

{

console.writeline(“键是{0},值是{1}”kv.key,kv.value);

}

 

九、转换

1、装箱、拆箱

装箱:将值类型转换成引用类型。

拆箱:把引用类型转换成值类型。

 

2、里氏转换

1)子类可以赋值给父类。

父类:

Public class person

{

  Publicvoid sayhello()

  {

    Console.writeline(“我是中国人”);

  }

}

子类一:

Public class hubie:person

{

  Publicvoid sayhello()

  {

    Console.writeline(“我是湖北人”);

  }

}

子类二:

Public class jiangsu:person

{

  Publicvoid sayhello()

  {

    Console.writeline(“我是江苏人”);

  }

 

主函数:

 

Person china=new hubei();    //把子类对象赋值给父类。如果有一个地方需要父类作为参数,可以用一个子类对象代替。

 

 

 

2)如果父类中装的是子类对象,可以将这个父类强转为子类。

 

jiangsu js = (jiangsu)china;  //父类对象中装的是哪一个子类成员,才能转换成哪个子类的。这里的父类对象china前面被赋的值是hubei子类的,所以要强转成jiangsu子类的,会出错。

 

            hubie hb = (hubie)china;//这个会成功。

3IS

if (china isjiangsu)   //is的作用是,如果转换目标成功,则返回一个true. 先判断再转,避免拋异常。

            {

                jiangsu js = (jiangsu)china;   

            }

 

            else

            {

                Console.WriteLine("转换失败");

            }

 

 

4AS

jiangsu js1 = china asjiangsu//作用是,如果转换成功就继续执行,如果不成功刚返回值null。不会拋异常。这里js1的值就会是null.

 

十、委托

十一、反射

 

 

 

 

 

 

第二部分:文件、目录及文件流的操作

  • 文件的操作

1、  创建文件

File.create(@”c:\test\test.txt”).close();    //@是去除转义符。建好后就关闭,否则如果后面要写入内容就会出错。

2、  删除文件

File.Delete(@”c:\test\test.txt”);   

3、  复制文件

File.Copy(@”C:\test\test.txt”,@”c:\test\new.txt”); //复制文件并更名。

4、  移动文件或重命名

File.Move(@"d:\site\file\test7.txt", @"D:\site\file\newfile\test7.txt");

 

5、判断

if(File.Exists(@"d:\site\file\my.txt"))       //判断文件是否存在,如果存在先删除再建立。不存在,直接建立。

           {

               File.Delete(@"d:\site\file\my.txt");

               File.Create(@"d:\site\file\my.txt").close();

           }

            else

            {

                File.Create(@"d:\site\file\my.txt").close();

}

6、读取文件

(1)   File.ReadAllText(path); //读取文件中的内容,但把所读到的所有内容当一个字符串处理。返回值是字符串,不是字符串数组和集合。

(2)   File.ReadAllLines(path);//读取文件中的内容,但把每一行当一个字符串,返回值是一个字符串数组。

7、写入数据  //写入数据会覆盖原有的数据

1File.WriteAllLines(path,string[]);  //path是文件路径,string[]是要写入的字符串数组,一定要是数组。

2File.WriteAllText(path, string);  //path是文件路径,string是要写入的字符串。

 

8、追加数据  //追加数据是添加在后面,不会覆盖原有数据。

1File.AppendAllLines(path,string[]);  //path是文件路径,string[]是要写入的字符串数组,一定要是数组。

2File.AppendAllText(path,string); //path是文件路径,string是要写入的字符串。

9、设定文件属性

File.SetAttributes(path,FileAttributes.ReadOnly);//可以设置文件属性为只读,可写,隐藏等。

 

10、综合例:

 

staticvoid Main(string[] args)

        {

            string path = @"d:\site\file\my.txt";  //把常用的路径定义成一个字符串。

            string all = "";       //为遍历字符串拼接字符串赋一个空字符串。一定要先赋值。

           if(File.Exists(@"d:\site\file\my.txt"))       //如果文件存则为真,不存在为假

           {

               File.Delete(@"d:\site\file\my.txt");   

               File.Create(@"d:\site\file\my.txt").Close();//文件如存在,就先删掉此文件,马上再建一个,建好后马上关闭。

           }

            else

            {

                File.Create(@"d:\site\file\my.txt").Close();//如果文件不存在就直接建一个。

              

            }

 

string test= File.ReadAllText(@"d:\site\file\test.txt",Encoding.Default);

//读取另一个文件中的内容,存为一个字符串。

          string[] test1 = File.ReadAllLines(@"d:\site\file\test.txt", Encoding.Default); //读取另一个文件中的内容,存为一个字符串数组。

          File.AppendAllLines(path, test1);  //把字符串数组作为内容添加到path路径所指文件中,即my.txt中。如此时把test1换成test会报错,因为test只是一个字符串,不是一个数组.

          File.AppendAllText(path, test);    //把字符串添加到my.txt中。

          File.AppendAllText(path, "我是一个北方的狼");

          string[] s = File.ReadAllLines(@"d:\site\file\my.txt");  //读取my.txt中的内容,并赋值给一个字符串数组。

          foreach (var item in s) //遍历字符串数组

          {

 

              all += item.ToString();  //把字符串数组拼接成一个字符串。

 

          }

          //File.WriteAllLines(@"d:\site\file\test1.txt",s);   //把字符串数组的内容写入test1.txt中,原来的文件内容会被覆盖。

          //File.WriteAllText(@"d:\site\file\test.txt","我会覆盖你原来的内容");//把字符串的内容写入test1.txt中,原来的文件内容会被覆盖

           Console.WriteLine(all);

           Console.ReadKey();   

    }

 

 

 

 

     

  • 目录操作

1path类(路径的操作)

String str=@”d:\site\loready\p_w_picpath\3.jpg”;

Console.writeline(Path.GetFileName(str));   //获取路径中的文件名,显示为3.jpg

Console.writeline(Path.GetFileNameWithoutExtension(str));//获取文件名,但不包含拄展名,显示为3

Console.writeline(Path.GetExtension(str));  //获取扩展名,显示为jpg

Console.writeline(Path.GetDirectoryName(str)); //获取文件夹的名称,显示为d:\site\loready\p_w_picpath

Console.writeline(Path.GetFullPath(str));   //获取全目录,即显示为d:\site\loready\p_w_picpath\3.jpg

Console.writeline(Path.Combine(@”c:\a\”,”b.txt”));  //连接两个字符串作为路径,显示为c:\a\b.txt

其他方法见MSDN

 

2、目录的操作

Directory

Directory.Delete(@"d:\site\file\file_dir”) //删除一个目录

Directory.Move(@"d:\site\file\file_dir1",@"d:\site\file\file_dir");//移动一个目录到另一个目录,前面是源目录,后面是目的目录路径

            if(Directory.Exists(@"d:\site\file\file_dir"))//判断目录是否存在

            {

               string[]s=Directory.GetFiles(@"d:\site\file\file_dir");

//getfiles是获取目录下的文件及路径。

               for (inti = 0; i < s.Length; i++)

               {

                   dir += s[i];

                   

                  

                }

            }

            else

            {

               Directory.CreateDirectory(@"d:\site\file\file_dir");//创建一个目录

            }

            Console.WriteLine(dir);

            Console.ReadKey();

 

要想复制目录,思路是用递归的方法遍历源目录下的所有目录及文件,把这些目录和文件再复制到另一个地方。

 

 

 

 

  • 文件流操作(用于操作大文件)

 

把大文件碎片化操作,一块一块操作,而FILE类,则是文件一次性操作。

1、  Filestream(操作字节的,任何文件都可以操作)

1)读取数据

FileStream fs=newFileStream(@"d:\site\file\test.txt",FileMode.OpenOrCreate, FileAccess.Read);//第一个参数是要操作文件的路径;第二个参数是对文件的操作模式,是打开(Open),创建(Create),还是追加(Append)OpenOrCreate是如果文件不存在就创建并打开,如果文件存在就直接打开;第三个参数是对文件里的数据进行的操作,是读(fileaccess.read),还是写(fileaccess.write)

byte[] buffer=newbyte[1024*1024*1]//建立一个字节数组,并指定一次性读取文件的大小,这里为1M

 int r=fs.Read(buffer, 0, buffer.Length);   //第一个参数是指把读取到的内容存到buffer字节数组中,第二个参数是从哪里开始写入数据,0即是开始位置,buffer.length即表示每次最多读取数据的大小,即1M。返回的int类型值,是指读取到的字节数。

string s = Encoding.Default.GetString(buffer,0,r);  //把存放在字节数组中的数据流解码成字符串。0是从流的0位置开始解码,r是指解码的字节数。这样就会只解码刚才读的部分。

fs.Close();    //c#无法自动释放数据流,所以要先关闭数据流,再用dispose()释放流。

 fs.Dispose();

 Console.WriteLine(s);

 

 

2)写入数据

using (FileStream fswrite = newFileStream(@"d:\site\file\test.txt", FileMode.OpenOrCreate, FileAccess.Write))   //using中会自动释放流的资源。此处最后一个参数改成了写的状态。

   {

   string w = "我们的家在松花家上啊,那里有大豆高粱";

   byte[] buffer1 = Encoding.Default.GetBytes(w);    //把要写入的字符先转换成数据流,然后存入buffer1字节数组中。

  fswrite.Write(buffer1,0,buffer1.Length);           //第一个参数是字符数组,第二个参数是从哪里写入,第三个参数是写入的最大长度。

    Console.WriteLine("写入OK");

Console.ReadKey();

 

 

2、  streamreaderstreamwriter(操作字符的,即文本文件)

每次只读文本中的一行,要读完就要循环到文本的最后一行。

读:

Using(streamreader sr=new streamreader(@”d:\site\file\test.txt”,encoding.default)

{

While(!sr.endofstream)  //如果没读到文本的行尾

{

Console.writeline(sr.readline());  //就不停的读下一行并显示出来。

}

}

写:

Using(streamwriter sw=new streamwrite(@”d:\site\file\test.txt”,true)  //true表示追加到原文本后面,不会覆盖原文本。

{

Sw.write(“要写入的字符”);

}

 

第三部分:字符串操作、编码及正则表达式

一、字符串操作

字符串是引用类型且字符串对象是不可变的:即它们创建之后就无法更改,不能依据其堆中的存储地址找到它然后更改它。

如:string s=”123”;此时s在栈中指向堆中123的地址空间。

string s=”456”;此时对S重新赋值,但不会像其他类型一样,456会存到123原有的地址空间,替换掉123,而是在堆中重新开辟一个空间存值 456,且把s在栈中指向的地址改向456的地址。原来123在堆中仍然存在,并没有消失。

示例:

字符串的下标索引位是从0位开始。

String s=”abc_def”  //声明字符串

String b=”efg”

1、  计算字符串

s.Length  //字符串长度,返回的是整数。

2、  截取字符串

s.Substring(startend) //从字符串的第几位到开始到第几位结束间的所有字符串,可以只有start或只有end。从0位开始计算。

Cosole.writeline(s.substring(15)); //显示结果为:bc_de

3、  分割字符串

s.Split(“分隔符”)//用分隔符把字符串分成多个字符串,返回字符串数组

string[] test=s.split(‘_’);   //s字符串用_分成两个字符串,即字符串组,注意是单引号。

console.writeline(test[0]); //显示为abc

console.writeline(test[1]); //显示为def

 

4、  替换字符串

s.replace(“source_string”,”replace_string”) //用后面的字符串替换掉前面的字符串。

    console.writeline(“abc”,”ABC”);  //显示为ABC_def 

5、  比较字符串

s.Equals(b)  //比较两个字符串是否相同,如果相同则返回ture,否则返回falseS字符串和b字符串不一样,所以返回值为ture

 

6、  转换字符串

s.ToLower()  //把字符串转换成小写

s.ToUpper()  //把字符串转换成大写

7、  插入和删除字符串

(1)s.Insert(start要插入的字符串”);  //从第几位开始把后面的字符串插入到字符串中。

(2)s.Remove(start,end) //删除字符串中从start位开始到end位结束的字符。可以只有start或只有end

console.writeline(s.insert(4,b);  //显示为 abc_efgdef ,从第四位开始插入字符串b变量中的内容。

8、  匹配索引和包含判断

s.IndexOf(“bc”)// 从字符串头部开始搜索第一个匹配“bc”的在字符串中的位置索引。如果没有匹配,输出为-1。此如出显示出来,索引值为1,bc的开始下标为1开始。

s.Lastindexof(“de”)//从字符串尾部开始搜索第一个匹配“de”的位置索引。此处如显示出来,索引值为4

s.Contains("def")//判断字符串中是否包含字符串"def",有输出ture,没有输出false.此处返回为ture

9、  连接字符串

string[] arr = s.Split(‘_’);   //把字符串s用下划线分隔成两个字符串。这里是单引号。

此时arr[0]=”abc”;

   Arr[1]=”def”;

(1)      String.Join(“分隔符”,字符串数组名)  //把一个字符串数组连成一个字符串,用分隔符隔开。

Join(“分隔符”,字符串,字符串,字符串……) //把字符串连接成一个字符串,用分隔符隔开。

 

 

2String.Concat(字符串数组名)   //把字符串数组,连成一个字符串。 

String.Concat(字符串,字符串,….. //把字符串连成一个字符串。

 

例:

String s=”abc_def”

string[]arr = s.Split('_'); //分割成两个字符串

           

            stringtest=string.Join(",",arr);//用分隔符逗号把arr字符串数组中的字符串连接到一起。

Console.WriteLine(test); //显示为abc,def

            Console.WriteLine(string.Concat("qf","ef",”mf”));//显示为gfefmf

             Console.ReadKey();

Joinconcat的区别,只是一个有分隔符,一个没有。

 

(3)      StringBuilder

StringBuilder sb =newStringBuilder(); //定义一个类对象。

sb.Append(s);   //把字符串变量s中的内容添加到sb对象中。

sb.Append(b);  //把字符串变量b中的内容添加到sb对象中。

Console.writeline(sb.tostring()); //再把sb对象转换成字符串输出显示为abc_defefg

 

 

二、字符编码

 

编码:将字符串用怎样的形式保存为二进制。

Asc: 128  主要是美国用,英文和数字。

Ascii: 256  欧州用

Gb2312   国标,中国用,简体字

Big5      繁体字

Unicode   很全,世界上的编码都包含,全世界都能用,但太大了,会慢。

Utf-8      世界通用,主要用于web

 

 


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI