C#基础笔记
一.基础
1.Console.WriteLine();
//将指定值写入控制台并且换行
2.Console.Write();
//将指定值写入控制台
3.Console.ReadLine();
//读入一行,返回string值
4.Console.ReadKey();
//监听键盘事件,按任意键执行
5.Console.Read();
从控制台读取一个字符,返回int值
6.C# if判断中必须是bool表达式,不认只为值
7.在字符串前面加@
可以忽略转义字符
二.字符串和数组
1.Convert()
方法(任意数据类型转换为任意数据类型)
格式:数据类型 变量名 = Convert.To数据类型(参数);Convert.ToInt32();
//表示int类型Convert.ToInt16();/
/表示short类型Convert.ToInt64();
//表示long类型Convert.ToDouble();
//转换为double类型,会损失精度
2.Parse()
方法(字符串类型转化为任意数据类型)
格式:数据类型 变量 = 数据类型.Parse(字符串类型的值);
3.ToString()
方法(将任意的数据类型转为为字符串类型
格式:String 变量名 = 数据值.ToString();
值类型变量转化为引用类型变量称为装箱,反之为拆箱
4.string 不可变
5.C#使用new运算符创建一维数组
声明创建:
方法一:数组类型[] 数组名 = new 数组类型[数组长度];
方法二:数据类型[] 数组名;
数组名 = new 数据类型[数组长度];
初始化:
方法一创建时初始化:
数组类型[] 数组名 = new 数组类型[数组长度]{ 初始化列表 }; //数组长度可以省略
方法二先创建后初始化
数组元素=值
6.多维数组
声明创建:
数据类型[逗号列表] 数组名 = new 数组类型[维度长度列表]
例如创建四行三列数组:int[,] array = new int[4,3];
初始化:
int[,] array =new int[2,3]{{1,2,3},{4,5,6}};(可以省略维度长度列表,不能省略逗号)
注意:多维数组不允许初始化部分函数
7.定义字符串数组:string[] 数组名;
将字符串转化为字符数组:string[] 数组名 = 字符串名.Split(‘分隔符’)
8.字符串类型不能直接使用大于,小于的方式比较,要使用字符串的CompareTo()
方法,该方法的返回值是int类型
格式:
字符串1.CompareTo(字符串2);
相等返回0,当字符串1的字符顺序在字符串2前面时,返回-1,反之返回1
三.类和方法
1.get{}和set访问器
作用:对属性的读写进行限制,如商品价格不能为负数,对字段进行安全性保护
语法:
public 数据类型 属性名
{
get{获取属性的语句块;return 值;}
set{设置属性的语句块;}
}
get{}:获取属性的值,需要在get语句最后使用return关键字返回一个与属性数据类型兼容的值,属于只读属性访问器
set{}:用于设置属性的值,设置属性值时需要用到一个特殊的值 VALUE,它就是给字段赋的值,属于只写属性访问器
示例:
class book
{
private int id;
private string name;
private double price;
public int Id //图书编号是可读写属性 {
get { return id; }
set { id = value; }
}
public string Name //图书名称是只读属性 {
get { return name; }
}
public double Price //图书价格属性对字段的安全保护
{
get { return price; } //价格允许读
set
{
if (value < 0)//价格不能为负数
{
value = 0;
}
else
{
price = value;
}
}
}
在Visual Studio 2013中提供了界面操作方法实现对字段生成属性操作:打开指定类→选定要生成属性的字段,右键选择[重构]→[封装字段];
在get和set访问器后面不加大括号,而是直接加分号“:”,则称自动属性;
可以看出在定义字段属性时,属性的作用就是为字段提供get和set访问器操作都比较类似,在C#语言中可以可以将属性的定义简化为如下形式:
public 数据类型 属性名{get;set;}
简化后图书类代码:
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
在使用自动属性的方法时不能省略 get 访问器,如果不允许其他类访问属性值,可以加*问修饰符private
2.构造方法及方法重载
对类成员进行初始化,C#语言提供了两个特殊的方法,一个是构造方法处理对象的初始化,一个是析构方法在创建类的对象执行时实现垃圾回收和释放资源
(一)构造方法
没有定义构造方法,系统会自动生成一个空参构造
构造方法语法格式:
访问修饰符 类名(参数列表){
语句块
}
构造方法访问修饰符一般采用public类型,以便其他类中都可以创建该类对象,构造方法中参数可以是0个到多个参数;构造方法是在创建类的对象时被调用的,构造方法的语句块通常是完成对类中成员初始化的操作
(二)析构方法
析构方法主要用来回收类的实例所占用的资源,在对象销毁前,.NET的公共语言运行时会完全自动调用析构方法,并用垃圾回收器回收对象所占用的内存资源
析构函数语法:
~类名(){
语句块
}
在默情况下,编译器自动生成析构方法,因此C#不允许定义
空的析构方法,其实析构方法性能差,不推荐使用
(三)方法的重载
同一名称定义多个方法,这些方法的参数个数或参数类型不同
条件:1.重载的方法名必须相同;2.重载方法的形参个数或者类型必须不同
参数
引用参数:用ref定义,必须用变量赋值,不能是常量或表达式,形参实参指向同一内存地址
static void change(ref int x)
{
x = 100;
}
static void Main(string[] args)
{
int a = 1;
change(ref a);
Console.WriteLine(a);//输º?出?100
Console.ReadKey();
}
输出参数:用out定义,不需要对实参进行初始化,专用于把方法中的数据通过形参返回给实参,但不会将实参的值传递给形参。输出参数多用于一个方法需要返回多个值的情况,需要注意的是,在使用输出参数时,必须在方法调用完成前为参数初始化值
无论是形参还是实参,只要是输出参数,都必须添加out关键字
static void change(out int A,out int B)
{
A = 100;
B = 200;
}
static void Main(string[] args)
{
int a,b;
change(out a,out b);
Console.WriteLine(a);//输出100
Console.WriteLine(b);//输出200
Console.ReadKey();
}
4.嵌套类和内部类
嵌套类:
在类的内部定义的类型称为嵌套类,也称为内部类型。在类定义的类称为嵌套类,嵌套类可看作类中的一个成员,嵌套类默认修饰符为private.但也可设置public、internal、protected或peotected internal。嵌套类通常需要实例化对象之后,才能引用其成员,在访问嵌套类成员时必须加上外层类的名称
public class person //外部类
{
public class student //内部类
{
public string name;
public student(string myname)
{
this.name = myname;
}
public void show()
{
Console.WriteLine("我¨°叫D" + name);
}
}
}
class Program //主类
{
static void Main(string[] args)
{
person.student student = new person.student("王健林");
student.show();
Console.ReadKey();
//输出“我叫王建林”
}
}
部分类:
在C#语言中提供一个部分类,用于表示一个类的一部分。一个类可以由多个部分类构成,定义部分 类的语法形式如下:访问修饰符 partial class 类名
其中,partial是定义部分类的关键字。部分类主要用于当一个类中的内容较多时将相似类中的内容拆分到不同的类中,并且部分类的名称必须相同
部分类:
public partial class cmm
{
public string name { get; set; }
public int age { get; set; }
}
public partial class cmm
{
public void show()
{
Console.WriteLine("我叫{0},今年{1}岁",name,age);
}
}
测试类:
class Program
{
static void Main(string[] args)
{
cmm stu = new cmm();
stu.name = "王健林";
stu.age = 18;
stu.show();//输出我叫王健林,今年18岁
Console.ReadKey();
}
}
5.常用类
(一)Console类
Console.WriteLine();//将指定值写入控制台并且换行
Console.Write();//将指定值写入控制台
Console.ReadLine();//读入一行,返回string值
Console.ReadKey();//监听键盘事件,按任意键执行
Console.Read();从控制台读取一个字符,返回int值
(二)Random类
构造方法:Random(int seed) :
使用指定的种子值初始化Random类的新实例
方法:
Int Next(): 返回一个非负随即整数
Int Next(int max): 返回一个小于指定最大值的非负随机整数
Int Next(int min,int max): 返回一个在指定范围内的非负随机整数
Double NextDouble(): 返回一个介于0.0和1.0之间的随机浮点数
(三)string类
Format()方法:格式化字符串,通过占位符“{0},{1},…”的形式返回一个拼接字符串
DateTime dat = new DateTime();
string s =string.Format("当前日期是:{0}", dat.Date);
Console.WriteLine(s);
IsNullOrEmpty()方法:判断字符串是否为空:
string s = "fdgfd";
Console.WriteLine(string.IsNullOrEmpty(s));
Console.ReadKey();//输出false
Split()方法:用来分隔字符串
static void Main(string[] args)
{
string s = "I like English very munch";
string[] str =s.Split(' ');//以空格分隔存入字符串数组
Console.WriteLine(str.Length);//输出字符串数组长度
for (int i = 0; i < str.Length; i++)
{
Console.WriteLine("第{0}个单词是:{1}", i, str[i]);//输出字符串数组每个元素
}
Console.ReadKey();
}
Substring()方法:截取字符串,
string s = "IlikeEnglishverymunch";
string s1 = s.Substring(5, 7);
Console.WriteLine(s1);
Trim()方法:去除字符串两端的空格
四.继承
1.继承的概念
C#仅支持单继承,原则是单向且具有传递性
通过冒号实现继承:
Public class 子类名:父类名
2.构造方法(声明派生类的构造函数时必须用base关键字向父类构造函数传递参数)
父亲构造:
public string name;
public father(string myname)
{
this.name = myname;
}
儿子构造:
int age;
public son(string myname,int myage):base(myname)
{
this.age = myage;
}
在基类和派生类都有一个带参的构造函数,在创建派生类对象时,指定参数并通过base关键字来调用基类的构造函数,初始化从基类继承的字段,而派生类的构造函数只负责对自己扩展的字段进行初始化。
总之定义派生类带参构造函数并通过关键字base来调用基类构造函数,通过基类的构造函数对继承的字段进行初始化。
3.使用类图表示继承关系:找到类文件(拓展名是.cs文件),右击,查看类图
4.Object类:祖宗类
(一)Equals()方法
比较两个对象是否相等,是返回true,否返回false.如果是引用类型,则判断两个对象是否引用了同一个对象,在C#提供了一个静态方法和一个非静态方法
Equals(Object ob1,Object ob2); //静态方法
Equals(Object o); //非静态方法
实例:
class Program
{
static void Main(string[] args)
{
int a = 100;
int b = 100;
int c = 102;
Console.WriteLine(Equals(a, b));//使用静态方法,输出true
Console.WriteLine(a.Equals(c));//使用非静态方法,输出false
Console.ReadKey();
}
}
(二)GetHashCode()方法
返回当前System.Object的哈希码值,每个对象的哈希值都是固定的。该方法不含有任何参数,因此需要实例化对象来调用该方法。
father stu1 = new father();
son stu2 = new son();
Console.WriteLine(stu1.GetHashCode());//输出:37121646
Console.WriteLine(stu2.GetHashCode());//输出:45592480
(三)GetType()方法
GetType()方法用于获取当前实例的类型,返回值为System.Type类型。该方法不含任何参数,是静态方法,因此需要实例化对象来调用该方法
father stu = new father();
int a = 100;
Console.WriteLine(stu.GetType());//输出:second_text.father
Console.WriteLine(a.GetType());//输出System.Int32
(四)ToString()方法
返回一个对象实例的实例,在默认情况下将返回类的类型的限定名,任何类都可以重写ToString()方法,返回自定义字符串。对于其他的值类型,则是将值转化为字符串类型的值。
五.多态
一种事物的多种形态
六.抽象
(一)抽象类
格式:
public abstract class 类名{ 语句块 }
作用:提供多个派生类可以共享基类的公共方法定义。
特点:
1.必须使用abstract关键字修饰
2.抽象成员必须在抽象类中声明,但是抽象类不要求必须有抽象成员
3.抽象类是作用基类的,不能直接实例化对象,抽象类不能是密封类或静态类,其访问修饰符不能是private.
4.抽象类是具有构造函数的,派生类继承抽象类后,必须将抽象类中的抽象成员重写
(二)抽象方法、
不具有任何具体功能的方法,其唯一的作用是让派生类重写,在派生类中实现具体功能
格式:
[访问修饰符]abstract 返回值类型 方法名([参数列表]);
//没有方法体必须在抽象类中声明
抽象方法的重载:
Public override 方法名([参数列表]){ 语句块 }
重载的前提是派生类与抽象类具有继承关系
七.接口
一个接口定义了一个规范和标准。接口可以包含方法、 属性等成员,只描述这些成员的签名。签名只提供成员的数据类型、名称、 参数,不提供任何实现代码,具体实现由继承该接口的类实现。
实现某个接口的类型必须遵守该接口的规范和标准,即必须按接口所规定的签名格式进行实现,不能修改签名模式
定义语法:
Interface 接口名{
接口成员;
}
接口名:一般以I,开头,再加上其他的单词构成,例如创建一个USB的接口,可命名为IUsb
接口成员:接口中定义的成员不允许使用public、private、protected、internal访问修饰符;不允许static、virtual、abstract、 sealed修饰;接口成员不能是字段、 构造函数;接口成员可以是属性、方法、索引器和事件,接口中定义的方法不包含方法体;所以接口成员隐式的具有public修饰符,因此接口成员不必加任何修饰符
接口实现:
格式:
Class 类名 : 接口名
{
//类的成员及实现接口中的成员
}
1.隐式实现接口成员
隐式实现接口的方法比较常用,由于在接口中定义的成员默认式public类型的,所以隐式实现接口成员是将接口的所有成员以public访问修饰符修饰
class Computer:Icomputer
{
public int id{get ; set ;}
public string name{get;set;}
public void prin() {
Console.WriteLine("我隐式实现了接口");
}
}
2.显示实现接口成员
显示实现接口成员是指在实现接口时所实现的成员名称前含有接口名称作为前缀,需要注意的是,使用显示实现接口的成员不能再使用修饰符修饰,显示实现的成员不能通过类的实例来引用,必须通过所属的接口来引用,限制为接口访问成员
class Computer2:Icomputer//继¨¬承D接¨®口¨²
{
int Icomputer.id { get; set; }
string Icomputer.id { get; set; }
void Icomputer.prin()
{
Console.WriteLine("我显式实现了接口");
Console.ReadKey();
}
}
接口与抽象的比较
接口是一种规范或一种标准,抽象类是一种不能实例化的类,抽象与接口的区别如下:
使用接口实现多态
多态能使用类之间的继承关系实现,通过多个类继承同一接口。并实现接口中的成员也能完成多态的表示。使用接口实现多态需要满足以下两个条件。
(1)定义接口并使用类实现了接口中的成员
(2)创建接口的实例指向不同的实现类对象
interface Itest
{
string getMessage();
}
class test1 : Itest
{
public string GetMessage()
{
return string.Format("test1实º¦Ì现?");
}
}
class test2 : Itest
{
public string GetMessage()
{
return string.Format("test2实º¦Ì现?");
}
}
八、集合
所有集合类或集合相关的接口命名空间都是System.Collections
(一)ArrayList():集合元素可变,提供元素的添加、删除等操作
(二)Queue(队列):先进先出机制
Queue 队列名 = new Queue(队列长度,增长因子);
增长因子是指当需要扩大容量时,以当前容量值乘以因子的值来自动增加容量。
不能在创建实例时直接添加值Void Enqueue(object obj):
将对象添加到Queue实例的结尾处Objiect Dequeue();
移除并返回位于queue实例开始处的对象
(三)Static(堆栈):先进后出
(四)Hashtable(哈希表):集合中元素是以键值的形式存放,是DictionayEntry类型Void Add(object key,object value)
:向集合中添加元素Void Remove(object key)
:根据指定的key值移除对应的集合元素
(五)SortedLIst(有序键/值对列表):集合中的元素是以键值对形式存放,集合按照key值自动对集合中的元素排序,
九.泛型
命名空间:using System.Collections.Generic;
定义可空类型变量的语法具体形式:
System.Nullable<T> 变量名;
十.调试和异常处理
(一)异常处理语句
try…catch
在try语句中放置可能出现异常的语句,在catch语句中放置异常时处理异常的语句,catch允许多次使用,相当于多分支if语句,但仅仅执行其中的一个分支
static void Main(string[] args)
{
try
{
int[] a = new int[3];
for (int i = 0; i < 4; i++)
{
a[i] = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(a[i]);
}
}
catch (IndexOutOfRangeException i)
{
Console.WriteLine("数组越界");
}
Console.ReadKey();
}
输出:数组越界
try…finally
在try…finally形式中没有单独出现异常时处理的代码,finally语句无论try语句是否正确执行都会执行的语句。通常,在finally中编写的代码是关闭流,关闭数据库连接等操作,以免造成资源浪费,类无论是否捕捉到异常都必须执行的代码
static void Main(string[] args)
{
try
{
Console.WriteLine("hello try");
}
finally
{
Console.WriteLine("来了老弟");
}
Console.ReadKey();
}
输出:
hello try
来了老弟
try…catch…finally
使用最多的一种异常语句,在处理异常时能提供相应的异常处理,并能在finally语句中保证资源的回收
static void Main(string[] args)
{
try
{
int[] a = new int[2];
a[2] = 1;
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
Console.WriteLine("来了老弟");
}
Console.ReadKey();
}
输出:
索引超出了数组界限
来了老弟
(3)自定义异常
实际编程中会遇到未涉及的一些异常处理,想将数据的验证放置到异常处理中,如中学生年龄必须在12~25岁,此事需要用户自己定义异常来实现,自定义异常类必须继承Exception类
格式:
Class 异常类名 :Exception
{
}
抛出自己的异常语句是throw,具体语法格式如下:
throw(异常类名);
class MyException:Exception//自定义异常
{
public MyException(string message)//构造函数
: base(message)
{
}
}
class Program
{
static void Main(string[] args)
{
int age = int.Parse(Console.ReadLine());
try
{
if (age <= 12 || age >= 25)
{
throw new MyException("年龄必须在13岁到16岁之间");//抛出异常
}else{
Console.WriteLine("年龄在正常范围内");
}
}catch(MyException mye){
Console.WriteLine(mye.Message);
}
Console.ReadKey();
}
}
(3)调试
调试信息是运行时的过程,调试信息的类保存在System.Diagnostics命名空间Debug.WriteLine();
调试模式下使用Trace.WriteLine();
调试程序,发布程序都可以
十一.委托
委托某个方法来实现具体的功能
(一)命名方法委托
定义语法:
修饰符 delegate 返回值类型 委托名(参数列表);
实例化:
委托名 委托对象名 = new 委托(方法名);
十一.窗体应用
1.在使用窗体方法中,如果是当前窗体,调用方法时直接由this关键字来表示当前窗体,表现形式为“this.方法名(参数列表)”;如果操作其他窗体,则需要采用实例化窗体对象来实现,其表现形式为“窗体对象名.方法名(参数列表)
”
2.默认情况,应用程序第一个窗体被自动指定为启动窗体,应用程序开始运行时会首先显示这个窗体,如果想显示其他窗体,在程序主入口Program.cs
修改 Application.Run(new Form1());
语句中的new Form1(为要显示的窗体)