(C#) 精简 C# 入门(五)

最近在做一些需要用到 C# 开发的项目,许久未碰有些生疏,因此决定把语言的基础内容先都快速过一遍。为方便查阅,挑选最精简的部分整理于该博客。

【说明】

  1. 本系列的目标是整理出十个以内的博客(传送门),适合快速入门。目前更新到:精简 C# 入门(五)
  2. 本系列不适用于完全的编程初学者(未接触任何计算机语言),这一类读者建议仔细学习【参考资料】中的视频资源

【参考资料】
1.b站:【01_C#入门到精通】新手强烈推荐:C#开发课程,一整套课程

文章目录

  • #1 `Path` 类
  • #2 `File` 类
  • #3 文件流
    • 3.1 FileStream
    • 3.2 StreamReader & StreamWriter
  • #4 面向对象之——多态
    • 4.1 虚方法
    • 4.2 抽象类
    • 4.3 接口

#1 Path

Path 类为静态类,用于操作路径

类方法:

using System.IO;

[string] Path.GetFileName(path);                 // 获得 path 路径所指代的文件名
[string] Path.GetFileNameWithoutExtension(path); // 获得不包含文件格式的文件名
[string] Path.GetExtension(path);                // 获得文件格式
[string] Path.GetDirectoryName(path);            // 获得文件夹路径

// 示例
string path = @"C:\file1\test.txt";
Path.GetFileName(path)                 >>> "test.txt"
Path.GetFileNameWithoutExtension(path) >>> "test"
Path.GetExtension(path)                >>> ".txt"
Path.GetDirectoryName(path)            >>> "C:\file1"

#2 File

Path 类为静态类,用于操作文件

using System.IO;
using System.Text;

string path = @"C:\file1\test.txt";

[bool] File.Exists(path);                // 判断文件是否存在

File.Create(path);                      // 创建文件
File.Delete(path);                      // 删除文件
File.Copy(path, @"C:\file1\new.txt");   // 复制文件,新文件名为 "new.txt"
File.Move(path, @"C:\file1\new.txt");   // 移动文件至新地址

读取

string path = @"C:\file1\test.txt";

[string] File.ReadAllText(path, Encoding.Default);    // 以字符串格式读取整个文件
[string[]] File.ReadAllLines(path, Encoding.Default); // 以字符串格式一行行读取文件
[byte[]] File.ReadAllBytes(path);                     // 以二进制格式读取文件
	// 将二进制数组转成 string
	[string] Encoding.Default.GetString(); 

写入

string path = @"C:\file1\test.txt";
string content = "Hello World!";
string[] contents = { "111", "222" };

// 覆盖写入
File.WriteAllLines(path, contents);
File.WriteAllText(path, content);
File.WriteAllBytes(path, Encoding.Default.GetBytes(content));

// 追加写入
File.AppendAllText(path, content)

#3 文件流

相较于 File 类对整体文件的读写,文件流对文件的读写是一点一点分步进行的,因此内存占用更少。

对应于 File 类中操作字符(WriteAllLines, WriteAllText)以及操作字节(WriteAllBytes)的方法,在文件流中有以下两种方法:

  1. FileStream:操作字节
  2. StreamReader & StreamWriter:操作字符

3.1 FileStream

using System.IO;

FileStream fsRead = new FileStream(path, 
	FileMode.XXX, // 操作系统打开文件的方式
	FileAccess.XXX, // 定义文件读写权限
);

(C#) 精简 C# 入门(五)_第1张图片
(C#) 精简 C# 入门(五)_第2张图片
类方法

// 创建示例(以下是两种常用的创建模式)
FileStream fsRead = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read);
FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);

// 从第 0 个字节开始,读取 buffer.Length 个字节,并存入 buffer
// buffer 为提前创建好的一个字节类型的数组
// 返回值为读取到的有效字节数
[int] fsRead.Read(buffer, 0, buffer.Length);
fsWrite.Write(buffer, 0, buffer.Length); // 将目标文件中 [0, buffer.Length] 个字符替换为 buffer 中储存的字符

fsRead.Close();   // 关闭流
fsRead.Dispose(); // 释放占用的资源

示例:使用 FileStream 读写 txt 文档

string path = @"C:\file1\test.txt";
byte[] buffer = new byte[1024*1024*5];

// 读取:方法 1
FileStream fsRead = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read);
int n = fsRead.Read(buffer, 0, buffer.Length);
string s = Encoding.Default.GetString(buffer, 0, n); // 将 buffer 的 [0, n] 个有效字节转换为 string
fsRead.Close();
fsRead.Dispose();

// 读取:方法 2
string s;
using(FileStream fsRead = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read))
{
	int n = fsRead.Read(buffer, 0, buffer.Length);
	s = Encoding.Default.GetString(buffer, 0, n);
}

// 写入
using(FileStream fsWirte = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{
	string str = "Hello World!";
	byte[] buffer = Encoding.Default.GetBytes(str);
	fsWrite.Write(buffer, 0, buffer.Length); 
}

上例中用到的 using(){ } 方法类似于 Python 中的 with 语句,即运行完大括号内的代码之后自动释放小括号内的代码所占用的资源

3.2 StreamReader & StreamWriter

类方法

StreamReader sr = new StreamReader(path);
StreamWriter sw = new StreamWriter(path);

[bool] sr.EndOfStream;  // 指示当前的流位置是否在流结尾
[string] sr.ReadLine(); // 读取输入流中的下一行字符串 

sw.Write("Hello World!"); // 覆盖写入
	// 如果想要继续写入,不覆盖之前的文本,可以在创建对象时添加一个布尔参数
	StreamWriter sw = new StreamWriter(path, true);

示例:读写 txt 文档

string path = @"C:\Users\Administrator\Desktop\dm.dll";

// 读取
using (StreamReader sr = new StreamReader(path))
{
    while (!sr.EndOfStream)
    {
        Console.WriteLine(sr.ReadLine());
    }
}

#4 面向对象之——多态

概念: 让一个对象能够表现出多种状态(类型)

为什么要使用多态? 便利性。例如,以下代码的运行结果为:

发出了叫声
发出了叫声

(C#) 精简 C# 入门(五)_第3张图片
这显然同我们的目标结果不符合:

喵
汪

在不不了解多态之前,我们可以将 for 循环改为以下形式来实现目标,但问是复杂冗长,而且会随着子类数目的增长变得更复杂:

for (int i = 0; i < animals.Length; i++)
{
    if (animals[i] is Cat)
    {
        ((Cat)animals[i]).Shout();
    }
    else if (animals[i] is Dog)
    {
        ((Dog)animals[i]).Shout();
    }
    animals[i].Shout();
}

多态的实现方式: 虚方法、抽象类、接口

4.1 虚方法

步骤:

  1. 将父类中的函数标记为虚方法,关键字 virtual
  2. 将子类中的同名函数标记为重写,关键字 override

例如:

public class Animal
{
    public virtual void Shout() { Console.WriteLine("发出了叫声"); }
}
public class Cat : Animal
{
    public override void Shout() { Console.WriteLine("喵"); }
}

4.2 抽象类

步骤:

  1. 将父类标记为抽象类,其中的函数标记为抽象方法,关键字 abstract
  2. 将子类中的同名函数标记为重写,关键字 override

例如:

public abstract class Animal
{
    public abstract void Shout();
}
public class Cat : Animal
{
    public override void Shout() { Console.WriteLine("喵"); }
}

Others for 抽象类

  1. 不能单独创建抽象类的对象,但可以创建其子类
  2. 当子类继承抽象类时,需要重写其中的抽象方法,否则报错(可以使用 Alt+Shift+F10 自动填充),除非这个子类也是抽象类
  3. 抽象类中可以包含非抽象成员,即属性、字段、函数
  4. 抽象方法所定义的输入和输出,规定了其子类继承的同名函数也必须要有一样的输入和输出

4.3 接口

你可能感兴趣的:(C#,c#,visual,studio)