1.为项目添加dll引用
在“解决方案资源管理器”面板中选择项目,单机鼠标右键,弹出菜单中选择“添加”->“引用”打开引用管理器,选择浏览添加自己需要的dll文件即可
2.位移运算符使用技巧
在进行位移运算时,当数值的二进制数每次向左移1位就相当于乘以2,当数值每次向右移1位就相当于除以2
3.将字母全部转换为大写或小写
3.1 转换大写
string str = "demo".ToUpper();
System.Diagnostics.Debug.WriteLine(str);
3.2 转换小写
string str = "demo".ToLower();
System.Diagnostics.Debug.WriteLine(str);
4.正则表达式
5.控制窗体
//设置窗体居中显示
this.StartPosition = FormStartPosition.CenterScreen;
//设置窗体左(上)边缘与屏幕左(上)边缘之间的距离
this.Left = Convert.ToInt32("10");
this.Top = Convert.ToInt32("20");
//设置窗体始终在最顶层显示 (只要将窗体的 TopMost 属性设为 true 即可)
//设置窗体大小
this.Width = 300;
this.Height = 100;
//根据桌面大小调整窗体大小
int DeskWidth = Screen.PrimaryScreen.WorkingArea.Width; //获取桌面宽度
int DeskHeight = Screen.PrimaryScreen.WorkingArea.Height; //获取桌面高度
this.Width = Convert.ToInt32(DeskWidth *0.8);
this.Height= Convert.ToInt32(DeskHeight *0.8);
//自定义最大化、最小化和关闭按钮
Form.WindowState = FormWindowState.Minimized; //最小化
Form.WindowState = FormWindowState.Maximized; //最大化
Form.WindowState = FormWindowState.Normal; //最大化后还原窗体
Form.Close(); //关闭
//禁止改变窗体大小 (通过将窗体的 FormBorderStyle 属性设置为 FixedDialog 即可)
6.out、ref、params(三个高级参数的使用)
/************************out************************/
/*方法使用return 只能返回一个值(一个数值或一个指针值),out参数可以帮助我们在一个方法中返回多个值,不限类型。
在使用out参数的时候需要注意:
在调用方法之前,对out参数传递的变量只需声明,可以赋值也可以不赋值,赋值也会在方法中被覆盖掉。
方法使用了out参数传递变量时,就是要返回值,所以必须在方法内为其赋值。
方法的参数使用out关键字修饰时,在调用该方法时,也要在out参数传递的变量前面加上out关键字才行。*/
static void Main(string[] args)
{
// 使用out参数返回一个数组的最大值、最小值
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int max;
int min;
GetMaxMinSumAvg(nums, out max, out min);
Console.WriteLine(max);
Console.WriteLine(min);
Console.ReadKey();
}
public static void GetMaxMinSumAvg(int[] nums, out int max, out int min)
{
max = nums[0]; // out参数传递的变量必须在方法内为其赋值
min = nums[0];
if(nums.Length > 0)
{
for (int i =0; i < nums.Length; i++)
{
if (nums[i] > max)
max = nums[i];
if (nums[i] < min)
min = nums[i];
}
}
}
/************************ref************************/
/*ref 关键字,和out一样,可以使得参数通过引用来传递。换句话说,ref能够让你直接对原来那个数进行操作,而不是将原数复制一份,对那个复制项进行操作。
ref参数的作用:
与out不同的是,它可以双向传值,主要适用于场景内部对外部的值进行改变的情况。换句话说,ref参数侧重于将一个已经初始化了的变量以参数的形式带到一个方法中进行改变,改变完成后,再将改变后的值带出来。
ref的作用主要是让值类型或string这种特殊类型的引用类型能够像其他引用类型一样在方法中进行了值的改变,在方法结束之后,能够将值保存下来。
在使用ref参数需要注意:
ref参数传递的变量在传递之前一定要对其进行初始化赋值。
方法的参数使用ref关键字修饰时,在调用该方法时,也要在out参数传递的变量前面加上ref关键字才行。
方法使用了ref参数传递变量时,不同于out,没有要求一定在方法中对ref所修饰的变量进行赋值,所以可以不赋值。*/
static void Main(string[] args)
{
int count = 5; // ref修饰的变量,必须对其赋初值
Add(ref count);
Console.WriteLine(count);
Console.ReadKey();
}
public static void Add(ref int i){
i += 5; // 不一定要赋值
}
像是c++里的&
/************************params可变参数************************/
/*params 关键字可以使得在参数个数可变处采用参数的数组型参数,比如 int sum(params int[] values)。
可变参数的作用:使得个数不确定的可变参数以数组的形式传递,适合于方法的参数个数未知的情况时,用于传递大量的数组集合参数。
可变参数在使用时需注意:
不允许将params修饰符与ref和out修饰符组合起来使用。
当方法的参数列表中有多个参数时,params修饰的参数必须放在最后,不能放在前面,以免程序不好确定参数究竟有多少个而报错。比如:
int Sum(int initial, params int[] arr)
一个方法当然可以包含可变参数和不变参数,两个可以同时使用。*/
public static int Sum(int initial, params int[] arr){
int sum = initial;
for(int i = 0; i < arr.Length; i++)
sum+=arr[i];
}
return sum;
}
传入的int[] arr数组在调用时可以随便更改其传入的大小
7.类修饰符
abstract 不能创建该类的实例,这意味着该类的作用是作为基类,抽象类不能密封
internal 该类只能从同一个程序集的其他类中访问。这是嵌套类型的默认访问方式
new 只用于嵌套的类,它指明类隐藏一个同名的被继承成员
private 嵌套类,只能定义它的类中访问
protected 嵌套类,只能从定义它的类中和自此派生的类中访问
public 该类的实例可以被任何其他类访问
sealed 该类不能作为其他类的基类
8.接口(Interface)
/*继承"基类"跟继承"接口"都能实现某些相同的功能,但有些接口能够完成的功能是只用基类无法实现的
1.接口用于描述一组类的公共方法/公共属性. 它不实现任何的方法或属性,只是告诉继承它的类 《至少》要实现哪些功能,继承它的类可以增加自己的方法.
2.使用接口可以使继承它的类: 命名统一/规范,易于维护.比如: 两个类 "狗"和"猫",如果它们都继承了接口"动物",其中动物里面有个方法Behavior(),那么狗和猫必须得实现Behavior()方法,并且都命名为Behavior这样就不会出现命名太杂乱的现象.如果命名不是Behavior(),接口会约束即不按接口约束命名编译不会通过.
3.提供永远的接口。 当类增加时,现有接口方法能够满足继承类中的大多数方法,没必要重新给新类设计一组方法,也节省了代码,提高了开发效率. */
接口不可以实例化对象
抽象类也不可以实例化对象
静态列也不可以实例化对象
接口可以继承并且可以多继承(接口只能继承接口)
一个类继承一个父类和一个接口,必须把父类写在接口前面
namespace MyDemo2
{
public interface IBook
{
//接口中不允许添加访问修饰符,默认就是public
//不能有方法体
//不能又字段及变量
int ID { get; set; }
string Name { get; set; }
double Price { get; set; }
double SalePrice(int discount);
}
class Book : IBook
{
//隐式的实现接口中的属性
public int ID { get; set; }
public string Name { get; set; }
public double Price { get; set; }
//隐式实现接口中的方法
public double SalePrice(int discount)
{
double salePrice = Price * discount * 0.1;
return salePrice;
}
}
class Program
{
static void Main(string[] args)
{
#region
Book book = new Book();
book.ID = 1001;
book.Name = "三国演义";
book.Price = 50;
Console.WriteLine("id:{0},书名:{1},定价{2},折后价{3}",book.ID,book.Name,book.Price,book.SalePrice(8));
Console.ReadKey();
#endregion
}
}
}
9.静态存储区域、堆存储区域、栈存储区域
静态
1.如果你想要你的类当作一个“工具类”去使用,这时候可以考虑将类写成静态类
2.静态类在整个项目中资源共享
3.只有程序全部结束后,静态类才能释放资源
10.构造函数
作用:帮助我们初始化对象(给对象的每个属性一次赋值)
构造函数是一个特殊的方法:
1.构造函数没有返回值,连void也不能写。
2.构造函数的名称必须和类名一样。
3.必须是public。
创建对象的时候会执行构造函数。
构造函数是可以重载的。
类当中会有一个默认的无参数的构造函数,当你写一个新的构造函数之后,不管是有参数还是无参数的,那个默认的
无参数的构造函数都被干掉了。
11.new 关键字
new帮助我们做了3件事
1.在内存中开辟了一块空间
2.在开辟空间中创建对象
3.调用对象的构造函数进行初始化对象
在用作修饰符时,new 关键字可以显式隐藏从基类继承的成员。
例:
class Animal
{
public void Run()
{
}
}
class Cat:Animal
{
public void Run()
{
}
}
如果子类有和父类一样的成员的时候,子类成员会将父类成员隐藏
隐藏过后子类将无法访问到父类该成员。如果刻意为之,我们可以使用new关键字显式的说明,从而提高可读性;
例:
class Cat:Animal
{
public new void Run()
{
}
}
12.继承
继承的特性
1.继承的单根性:
一个子类只能有一个父类,就好比一个人只有一个父亲。
2.继承的传递性:
例如, ClassC 派生自 ClassB,并且 ClassB 派生自 ClassA,则 ClassC 会继承在 ClassB 和 ClassA 中声明的成员。
子类会默认调用父类的无参构造函数,如果想要调用父类的有参构造函数需要加上关键字:
:base();
例:
A(string a,string b,int c):base(a,b,c)
在c#中,所有类都直接或间接的继承object类(当我们定义一个类的时候,如果没有给该类指定继承一个类,那么这个类就继承了object类)
13.Path类(操作路径)
1.快速获得一个文件路径下的文件名
string str = @"C:\path\demo\av.wav";
Console.WriteLine(Path.GetFileName(str)); //av.wav
2.快读获得文件名但是不包括扩展名
Console.WriteLine(Path.GetFileNameWithoutExtension(str)); //av
3.获得文件扩展名
Console.WriteLine(Path.GetExtension(str)); //.wav
4.获取文件所在文件夹目录
Console.WriteLine(Path.GetDirectoryName(str)); //C:\path\demo
5.获取文件全路径
Console.WriteLine(Path.GetFullPath(str)); //C:\path\demo\av.wav
14.File类(操作文件)
1024byte = 1kb;
1024kb = 1M;
1024M = 1G;
1024G = 1T;
1024T = 1PT;
1.创建文件
//将会在桌面创建一个test.txt文件
File.Create(@"C:\Users\XXX\Desktop\test.txt");
2.删除文件
File.Delete(@"C:\Users\XXX\Desktop\test.txt");
3.复制一个文件
File.Copy(@"C:\Users\XXX\Desktop\test.txt",@"C:\Users\XXX\Desktop\new.txt");
4.读文件
//一行一行读
string[] contents = File.ReadAllLines(@"C:\Users\XXX\Desktop\test.txt",Encoding.Default);
foreach(string item in contents)
{
Console.WriteLine(item);
}
//读取整个文件数据
string str = File.ReaAllText(@"C:\Users\XXX\Desktop\test.txt",Encoding.Default);
5.写文件
//以行的形式写入
File.WriteAllLines(@"C:\Users\XXX\Desktop\test.txt",new string[] {"aaa","bbb"});
//整体写入
File.WriteAllText(@"C:\Users\XXX\Desktop\test.txt","aaabbb");
//追加写入
File.AppendAllText(@"C:\Users\XXX\Desktop\test.txt","看看是否覆盖原数据");
6.文件流
//FileStream操作字节的 可以操作任何类型的文件
//File 操作字符
读
//创建FileStream对象
FileStream fsRead = new FileStream(@"C:\Users\XXX\Desktop\test.txt",FileMode.OpenOrCreate,FileAccess.Read);
byte[] buffer = new byte[1024*1024*5]; //5M
//rr为返回的实际读取字节数
int rr = fsRead.Read(buffer,0,buffer.Lrength);
//将字节数组中每一个元素按照指定的编码格式解码成字符串
string s = Encoding.UTF8.GetString(buffer,0,rr);
//关闭流
fsRead.Close();
//释放流所占用的资源 文件流需要手动释放资源
fsRead.Dispose();
写
//using帮助我们释放流资源
using(FileStream fsWrite = new FileStream(@"C:\Users\XXX\Desktop\test.txt",FileMode.OpenOrCreate,FileAccess.Write))
{
string str = "看我有没有把你覆盖掉";
byte[] buffer = Encoding.UTF8.GetBytes(str);
fsWriye.Write(buffer,0,buffer.Length);
}
7.多媒体文件复制
string source = @"C:\Users\XXX\Desktop\test.wmv";
string target= @"C:\Users\XXX\Desktop\new.wmv";
CopyFile(source,target);
public static void CopyFile(string source,string target)
{
//创建一个负责读取的流
using(FileStream fsRead = new FileStream(source,FileMode.Open,FileAccess.Read))
{
//创建一个负责写的流
using(FileStream fsWrite = new FileStream(target,FileMode.OpenOrCreate,FileAccess.Write))
{
byte[] buffer = new byte[1024*1024*5];
//因为文件可能会比较大,所以在读取的时候应该通过一个循环读取
while(true)
{
//返回本次读取实际字节数
int rr = fsRead.Read(buffer,0,buffer.Length);
if(0 == rr)
break;
fsWrite.Write(buffer,0,rr);
}
}
}
}
15.编码
ASC 128
ASCII 256
GB2312 简体字
Big5 繁体字
unicode 较全,但是解析起来慢
UTF-8 web
编码:将字符串已怎样的形式保存为二进制
乱码:产生乱码的原因:
是保存这个文件所采用的编码和打开这个文件采用的编码不一致。
16.装箱和拆箱
装箱:就是将值类型转换为引用类型
int n = 10;
object 0 = n; //装箱
拆箱:将引用类型转换为值类型
int nn = (int)o; //拆箱
17.多态
概念:让一个对象能够表现出多种的状态(类型)
实现多态的3种手段:1、虚方法 2、抽象类 3、接口
1 虚方法
//将父类的方法标记为虚方法,使用关键字virtual,这个函数可以被子类重新写一遍
//子类方法需要添加override
class Animal
{
public virtual void Run()
{
}
}
class Cat:Animal
{
public override void Run()
{
}
}
2 抽象类
//当父类中的方法不知道如何去实现的时候,可以考虑将父类写成抽象类,将方法写成抽象方法
//使用abstract将类标记为抽象类
class abstract Animal
{
public abstract void Run();//抽象方法不允许有方法体"{}"
}
class Cat:Animal
{
public override void Run() //子类重写
{
}
}
class Dog:Animal
{
public override void Run() //子类重写
{
}
}
void Main()
{
Animal a = new Cat();
a.Run();
Animal b = new Dog();
b.Run();
}
18.访问修饰符
public:公开的公共的
private:私有的,只能在当前类的内部访问
protected:受保护的,只能在当前类的内部以及该类的子类中访问
internal:只能在当前项目中访问,在同一个项目中和public权限相同
protected internal:protected+internal
1.能够修饰类的访问修饰符只有两个:
public || internal
当创建一个类时,如果没有指定访问修饰符则默认为internal
2.可访问性不一致
子类的访问权限不能高于父类的访问权限,(如果子类public修饰,父类internal---会暴露父类成员)
19.设计模式
20.序列化和反序列化、部分类、密封类
序列化:就是将对象转换为二进制
反序列化:就是将二进制转换为对象
作用:传输数据
部分类:用partial关键字修饰
密封类:用sealed关键字修饰,其他类不可继承密封类,但是密封类可以继承其他类