.NET 基础知识

.net程序基本编写、执行流程(c#)
      1>编写c#代码,保存为.cs文件。
      2>通过csc.exe程序来将.cs文件编译为.net程序集(.exe或.dll)。此时的exe或dll并不是机器码(cpu不可理解)。【>csc /out:c:\a.exe c:\program.cs】   C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe
      3>程序运行时通过JIT编译(Just In Time)即时编译,将程序集编译为cpu能理解的机器码,这时cpu才能执行。(这个编译过程会与当前机器有关(根据当前机器的内存、cpu等))。

垃圾回收

垃圾回收器,只回收托管堆中的内存资源,不回收其他资源(数据库连接、文件句柄、网络端口等)。
•没有变量引用的对象。没有变量引用的对象,表示可以被回收了(null),断了线的风筝,再也回不来了。
•回收时间不确定,当程序需要新内存的时候开始执行回收。
•GC.Collect();//手动调用垃圾回收器。不建议使用,垃圾回收时会暂停一下(非常短暂)让程序自动去GC。
 
垃圾回收器中“代”的概念:
•共3代:第0代、第1代、第2代。
•各代的回收频率:第0代最高,其次第1代,再次第2代。也就是说越老的对象生存几率越大。
.net中垃圾回收机制:mark-and-compact(标记和压缩),一开始假设所有对象都是垃圾。
除了内存资源外的其他资源怎么办?~或者Dispose()

最基本的5个设计原则

单一职责原则(SRP:Single Responsibility Principle):一个类,应该仅有一个引起它变化的原因,不要将变化原因不同的职责封装在一起,而应该隔离。

开放封闭原则(OCP,Open Closed Principle):软件实体应当对修改关闭,对扩展开放。

依赖倒置原则(DIP,Dependency Inversion Principle):依赖抽象,而不要依赖于具体,因为抽象相对稳定。

接口隔离原则(ISP,Interface Segregation Principle): 尽量应用专门的接口,而不是单一的总接口,接口应该面向用户,将依赖建立在最小的接口上。

Liskov替换原则(LSP,Liskov Substitution Pinciple): 子类必须能够替换其基类。

合成/聚合复用原则(CARP,Composite/Aggregate Reuse Principle)在新对象中聚合已有对象,使之成为新对象的成员,从而通过操作这些对象达到复用的目的。合成方式较继承方式耦合更松散,所以应该少继承。

•接口→抽象类→父类→具体类(在定义方法参数、返回值、声明变量的时候能用抽象就不要用具体。)
 
params 可变参数  
·一个函数中只能一个参数带params关键字;
·带params关键字的参数必须是最后一个参数;
·带params关键字的参数类型必须是一维数组(传递一个或者多个参数);

类中的成员,如果不加访问修饰符,则默认为private

类如果不加访问修饰符,则默认为internal

 

继承:

---好处

1.代码重用

2.多态(里氏替换原则LSP)

---特征

1.当写好一个类以后,默认会存在一个没有参数的构造函数(即便我们不写构造函数,也会存在这么一个无参的构造函数)

2.当手动添加一个构造函数以后,会将默认的无参数的构造函数覆盖掉。

3.类的构造函数是不能被继承的。只能在子类中去调用父类的构造函数。 

编译是为父类对象,但运行却是一个子类对象。具体特征如下:
  1.被声明为父类对象
  2.拥有父类属性
  3.占用子类的内存空间
  4.子类方法覆盖父类的方法时,此时对象调用的是子类的方法;否则,自动调用继承父类的方法.

 

抽象类和接口的区别

接口定义类的公共行为,抽象类定义类的公共实现

一个类只能继承自一个类(抽象类),但是可以同时实现多个接口

接口中不能有实现,抽象类中可以有未实现成员也可以有实现的成员

接口中未实现的方法必须在子类中实现,抽象类中未实现的成员必须在子类中重写

好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染。   

 

什么时候使用抽象类,什么时候使用接口

  抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能。

1.飞机会飞,鸟会飞,他们都继承了同一个接口“飞”;但是F22属于飞机抽象类,鸽子属于鸟抽象类。
2. 就像铁门木门都是门(抽象类),你想要个门我给不了(不能实例化),但我可以给你个具体的铁门或木门(多态);而且只能是门,你不能说它是窗(单继承);一个门可以有锁(接口

 

虚方法和抽象方法的区别

虚方法必须有实现(哪怕是空实现),抽象方法必须没有实现

抽象方法必须在抽象类中声明,虚方法可以出现在抽象类中

抽象方法必须在子类中重写,虚方法可以被重写

实现多态的主要手段:

1.虚方法virtual

2.抽象方法abstract

3.接口。

关于虚方法需要注意的几点:

1.父类中如果有方法需要让子类重写,则可以将该方法标记为virtual

2.虚方法在父类中必须有实现,哪怕是空实现。

3.虚方法子类可以重写(override),也可以不重写。

    public abstract class MyBase
    {

       protected abstract void Search();

        
        protected virtual void Save()
        {
         dbContent.SaveChange();
        }
    }

static  

普通类中的静态成员static
  •只能通过类名访问
  •静态方法中只能访问静态成员,或通过对象访问实例成员。(就像main方法)
  •多个对象共享同一个静态成员。
class Program
    {
        static void Main(string[] args)
        {
            Person p = new Person();
            p.Name = "张三";
            Person.age = 18;
            Test t = new Test();
            t.MyMethod();
            Console.WriteLine(p.Name);
            Console.WriteLine(Person.age);
            Console.ReadKey();
        }
    }
View Code
静态类(一般都用作工具类,里面都是一些工具函数)
  •Math、Console、Convert 等都是静态类。
  •静态类中只能包括静态成员
  •静态构造函数不能有参数、不能有访问修饰符(默认为private)。静态构造函数在第一次使用该静态类的时候只执行一次。
 
l静态成员属于类所有,非静态成员属于类的实例所有
lC#静态方法属于类所有,类实例化前即可使用
l在实例方法中可以直接调用静态方法,在静态方法中不可以直接调用实例方法
l静态方法和静态变量创建后始终使用同一块内存(静态存储区),而使用实例的方式会创建多个内存
l少使用静态类,静态类、静态成员所分配的内存在程序退出时才会释放。
 
l1.在实例类中使用静态成员。
•账户类:(实例类)
•class Account
•{
•UserName //用户名
•Address //地址
•Total //存款额
•static Rate //利率,由于该银行采用浮动利率,每天的利率根据当天的挂牌利率(基准利率)来计算,所以“利率”不适合作为每个对象单独的一个数据。
•}//当多个对象共享同一个数据的时候就可以在实例类中加入静态成员。
 
l2.使用静态类
•在项目中需要频繁用到的一些工具类,例如:Math、Console、Convert 等。或者模拟“全局变量”的时候。
 
多态:为了程序的可扩展性。
l多态的作用:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异, 写出通用的代码,做出通用的编程,以适应需求的不断变化。
lis-a:可以用来验证继承关系中是否合理。(can do,验证实现接口是否合理*)
lif(obj is 类型A)//obj是父类类型对象,”类型A”是子类类型。
l关键字as (类型转换)、 is(通常类型转换前需要通过is来判断一下类型。)
 
实现多态的方式:
1.virtual,子类重写父类中的方法。
2.abstract,子类重写父类中的方法。(抽象类中可以有实例成员也可以有抽象成员。)抽象的父类或者接口如果子类没有实现其方法是不能创建父类对象的。
3.接口,接口中的所有成员必须被子类中全部实现,除非子类是抽象类,把接口中的成员标记为抽象的。接口中可以有属性、方法、索引器等(本质上也是方法),但不能有字段(因为字段是实现)
 
 
enum

enum Gender { Male,Female}

把字符串转换成枚举Gender g = (Gender)Enum.Parse(typeof(Gender), "Male");

 

struct

就是小类,值类型,不能继承类,可以实现接口,不能有显示无参构造函数(隐式),除非字段被声明为 const 或 static,否则无法初始化.

结构体适合一些小型数据结构,这些数据结构包含的数据以创建结构后不修改的数据为主。例如:struct类型适于表示Point、Rectangle和Color等轻量对象。

 

String字符串的一些特性:

不可变性(ToUpper演示)
字符串暂存池(拘留池)(针对字符串常量)
•内部维护一个哈希表key为字符串,value是地址。每次为一个新变量赋值都会找key中是否有,如果有则直接把value中的地址赋值给新变量
•对于动态字符串本身在哈希表中没有,通过Intern可以添加到该哈希表中,目的为了提高性能。
•String.Intern(xx), Intern 方法使用暂存池来搜索与 str 值相等的字符串。如果存在这样的字符串,则返回暂存池中它的引用。如果不存在,则向暂存池添加对 str 的引用,然后返回该引用。
•String.IsInterned(xx),此方法在暂存池中查找 str。如果已经将 str 放入暂存池中,则返回对此实例的引用;否则返回 nullNothingnullptrnull 引用

StringBuilder

StringBuilder仅仅是拼接字符串的工具,大多数情况下还需要把StringBuilder转换为String.

 

Equals、==、ReferenceEquals方法

•string的Equals方法判断的是字符串的内容是否相同(重写了Object中的Equals方法。)
•而object中的Equals方法是判断对象的地址是否相同
•查看String类的==运算符,内部调用的也是Equals
•判断两个对象是否相同:object. object.ReferenceEquals();
 

数组

数组特点:类型统一、长度固定。

Array是所有数组的父类。

 
集合
常用集合
•“类似数组”集合:ArrayList(可变长度,类型任意,无论什么类型的数据放到ArrayList中以后都变成了Object类型,取出的数据需要类型转换,非泛型)、List<T>(泛型)
•“键值对”集合(“哈希表”集合):Hashtable(非泛型)、Dictionary<K,V>(泛型)
•“堆栈”集合:Stack、Stack<T>(LIFO)
•“队列”集合:Queue、Queue<T>(FIFO)
•“可排序键值对”集合:(插入、检索没有“哈希表”集合高效)
•SortedList、SortedList<K,V> (占用内存更少,可以通过索引访问)
•SortedDictionary<K,V> (占用内存更多,没有索引,但插入、删除元素的速度比SortedList快)
•Set 集合:无序、不重复。HashSet<T>,可以将 HashSet类视为不包含值的 Dictionary集合。与List<T>类似。SortedSet<T>(.net4.0支持,有序无重复集合)
•“双向链表”集合:LinkedList<T>,增删速度快。

System.Collections.Specialized 命名空间包含专用的和强类型的集合,例如,链接的列表词典、位向量以及只包含字符串的集合。

System.Collections.Concurrent 命名空间提供多个线程安全集合类。当有多个线程并发访问集合时,应使用这些类代替 System.Collections 和 System.Collections.Generic 命名空间中的对应类型。 

 

键值对集合原理示意图

.NET 基础知识_第1张图片

装箱、拆箱

必须是: 值类型→引用类型  或  引用类型→值类型。

拆箱时,必须用装箱时的类型来拆箱

 

文件操作常用相关类

File                  //操作文件,静态类,对文件整体操作。拷贝、删除、剪切等。
Directory         //操作目录(文件夹),静态类。
DirectoryInfo    //文件夹的一个“类”,用来描述一个文件夹对象(获取指定目录下的所有目录时返回一个DirectoryInfo数组。)
FileInfo            //文件类,用来描述一个文件对象。获取指定目录下的所有文件时,返回一个FileInfo数组。
Path                //对文件或目录的路径进行操作(很方便)【字符串】
Stream            //文件流,抽象类。
•FileStream      //文件流,MemoryStream(内存流),NetworkStream(网络流)
•StreamReader //快速读取文本文件
•StreamWriter  //快速写入文本文件
•GZipStream
 
Path类(对字符串操作)
目录和文件操作的命名控件System.IO
string ChangeExtension(string path, string extension) (*)
•修改文件的后缀,“修改”支持字符串层面的,没有真的给文件改名
•string s = Path.ChangeExtension(@"C:\temp\F3.png", "jpg")
string Combine(string path1, string path2)
•将两个路径合成一个路径,比用+好,可以方便解决不加斜线的问题,自动处理路径分隔符的问题
•string s = Path.Combine(@"c:\temp","a.jpg")
string GetDirectoryName(string path) (*)
•得到文件的路径名。Path.GetDirectoryName(@"c:\temp\a.jpg")
string GetExtension(string path) 得到文件的扩展名
string GetFileName(string path) 得到文件路径的文件名部分
string GetFileNameWithoutExtension(string path) 得到去除扩展名的文件名
string GetFullPath(string path) 得到文件的全路径。可以根据相对路径获得绝对路径。
string GetTempFileName()  得到一个唯一的临时文件名(*)
string GetTempPath() 得到临时文件夹的路径(*)
 
操作目录(Directory)
为了实现目录树,所以要掌握读取目录的类
Directory和DirectoryInfo
•void Delete(string path, bool recursive)     删除目录, recursive表示是否递归删除,如果recursive为false则只能删除空目录
•bool Exists(string path)      判断目录是否存在
•string[] GetDirectories(string path)  得到一个目录下的子目录
•string[] GetDirectories(string path, string searchPattern, SearchOption searchOption)    通配符查找目录下的子目录,可以搜索到隐藏文件。
•static string[] GetFiles(string path)  得到一个目录下的文件
•string[] GetFiles(string path, string searchPattern, SearchOption searchOption)   通配符查找目录下的文件
•DirectoryInfo GetParent(string path)  得到目录的父目录
•move()  //移动、剪切。只能在同一个磁盘中。目录没有Copy方法。可以使用Move()方法实现重命名。
•create()
 
StreamWriter(读取文本文件)
Stream把所有内容当成二进制来看待,如果是文本内容,则需要程序员来处理文本和二进制之间的转换。
用StreamWriter可以简化文本类型的Stream的处理
StreamWriter是辅助Stream进行处理的

 using (StreamWriter writer = new StreamWriter(stream, encoding))

 {

      writer.WriteLine("你好");

 }

 

正则表达式

 

你可能感兴趣的:(.NET 基础知识)