学习C#

day1

  ① 什么是 .NET ?

    .NET 包含两部分 .NET 平台 和 .NET FrameWork 框架

    .NET FrameWork 框架包含于 .NET 平台 , .NET FrameWork 框架提供环境和支撑保证 .NET 平台运行

  ② 什么是 C# ?

    C# 是一种面向对象、运行于 .NET Framework 上的高级程序设计语言 , 而 Java 既是语言又是平台

  ③配置 Visual Studio 2019 Community环境

  ④C#的项目构造 : 解决方案

              ----项目文件夹

                         ----类文件(.cs)

  ⑤类文件构造

       //导入命名空间 , 类似 Java 中的 import
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    //命名空间 , 类似 Java 中的 package
    namespace day01_MyFirstDemo{
      //声明类 , 跟 Java 不同的是 , C# 的类名不用跟文件名一致
      class Program{
        //声明方法 , 与 Java 一样
        static void Main(string[] args){
          Console.WriteLine("Hello World!");   //把 Hello World 打印在控制台中 , 类似 Java 的 System.out.println();
          Console.ReadKey();          //将用户此后第一次按下的按键 , 显示在控制台中 ,  暂时用来暂停程序 , 不知道有没有别的用处
        }
      }
    }    

 

  ④ 启动项目

    右键解决方案 → 属性 → 通用属性 → 启动项目 ,  选中当前选定内容 , 然后点击正上方的  或按下 F5 启动项目

day2

  ① 注释

    //单行注释

    /*多行注释*/

    ///文档注释  类似 Java 的 /**

  ② 常用快捷键

    代码格式化   Ctrl + K + D , 被我改成了 Ctrl + Alt + L

    快速注释代码  Ctrl + Shift + /

    快速移动光标  Shift + Home / Shift + End

  ③ 基本数据类型

    

 

  ④ 使用占位符方式打印字符串   

string name = "张三";
char sex = '';
int age = 22;
Console.WriteLine("姓名:{0},性别:{1},年龄:{2}",name,sex,age);
Console.ReadKey();

 

    

  ⑤ 定义一个字符串接收用户的输入

    string input = Console.ReadLine();

  ⑥ 转义符

    " \ " + 字符 , 和 Java 用法一样

    string 字符串的前面可以加 " @ " 将字符串里所有的 " \ " 当作普通字符对待 , 并且按照原格式输出 , 常用来表示路径

day3

  ① 结构体

    struct xxx{}

    和 class 类似,但是有以下不同

      类是引用类型,结构是值类型

      结构不支持继承

      结构不能声明默认的构造函数

day4

  ① delegate 委托

    委托是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。

    声明 :

      delegate <return type> <delegate-name> <parameter list>

    实例化 :

      public delegate void MyDelegate(string s);
      ......
      MyDelegate myDelegate = new MyDelegate(show);

    触发 :

      myDelegate("Hello World");

  ② event 事件

    事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。包含事件的类用于发布事件。这被称为 发布器 类。其他接受该事件的类被称为 订阅器 类。

    事件使用 发布-订阅(publisher-subscriber) 模型。

    发布器(publisher) 是一个包含事件和委托定义的对象。事件和委托之间的联系也定义在这个对象中。发布器(publisher)类的对象调用这个事件,并通知其他的对象。

    订阅器(subscriber) 是一个接受事件并提供事件处理程序的对象。在发布器(publisher)类中的委托调用订阅器(subscriber)类中的方法(事件处理程序)。

    声明 :

      public event MyDelegate myEvent;

    绑定 :

      a.myEvent += new A.MyDelegate(show);

    触发 :

      TransfEvent("Hello World");

  ③ out 和 ref

    使用 :  

          static void doFirst(out string msg) {
        msg = "信息";
      }
      static void doSecond(ref int num) {
        num = 10;
      }
      static void Main(string[] args) {  
        string msg;
        doFirst(out msg);
        int num = 0;
        doSecond(ref num);
      }

    相同 : 都按地址传递参数,使用后都将改变原来参数的数值。

    不同 : out 在传递参数前不需要将参数初始化 , ref 需要

  ④ parmas 可变参数

    public void doSome(parmas int[] nums){

    }

    和 Java 的 int... nums 一样

day5

  ① 封装 , 快捷键 Alt + Enter

    public class User {
            private String name;
            public string Name { get => name; set => name = value; }

    }

    ......

    User user = new User();

    user.Name="张三";

    Console.WriteLine("NAME: {0}  " , user.Name);

  ② static class 静态类

    静态类只允许有静态成员 , 不允许出现实例成员 ,并且不能被实例化

       public static class{
      private static int num;
      public static int Num{
        set{num = value;}
        get{return num;}
      }
    }

 

  ③ ~ 析构函数

    当程序结束的时候自动执行

    ~ ClassName()  {  
      ......
    }

day6

  ① FileStream 文件流

            //1. 读文件
            FileStream fs = new FileStream(@"路径",FileMode.OpenOrCreate,FileAccess.Read);
            byte[] buffer = new byte[1024*1024];
            int num = fs.Read(buffer, 0, buffer.Length);   //返回读取到的有效字节数
            fs.Close();     //关闭流
            fs.Dispose();   //释放流的资源
            string bufferStr = Encoding.UTF8.GetString(buffer,0,num);
            Console.WriteLine(bufferStr);
            */
            //2. 写文件
            /*string str = "这是一条测试语句";
            byte[] buffer = Encoding.UTF8.GetBytes(str);
            //覆盖文本
            //使用using自动关闭流和释放流的资源
            using ( FileStream fs = new FileStream(@"路径", FileMode.OpenOrCreate, FileAccess.Write)) {
                fs.Write(buffer,0,buffer.Length);
            }*/
            //追加文本
            using ( FileStream fs = new FileStream(@"路径", FileMode.Append, FileAccess.Write) ) {
                fs.Position = fs.Length;
                fs.Write(buffer, 0, buffer.Length);
            }
            //3. 复制文件
            using ( FileStream fsRead = new FileStream(@"源文件路径", FileMode.Open, FileAccess.Read) ) {
                using ( FileStream fsWrite = new FileStream(@"目标文件路径", FileMode.OpenOrCreate, FileAccess.Write) ) {
                    byte[] buffer = new byte[1024 * 1024];
                    while ( true ) {
                        int num = fsRead.Read(buffer, 0, buffer.Length);    
                        if ( num == 0 ) {
                            break;
                        }
                        Console.WriteLine("进行复制中");
                        fsWrite.Write(buffer, 0, num);
                    }
                }
            }                        

  ② Stream 流

            using ( StreamReader read = new StreamReader(@"路径") ) {
                while ( !read.EndOfStream ) {
                    Console.WriteLine(read.ReadLine());
                }
            }
            //true追加,false覆盖,默认是false
            using ( StreamWriter writer = new StreamWriter(@"路径", true) ) {
                writer.WriteLine("这是一条测试语句");
            }

  ③ virtual 虚方法

    和 JAVA 不同的是 , C# 默认是不使用多态的 , 需要在父类的方法上添加 virtual 关键字 , 并且在子类的方法上添加 override 关键字才可以使用

    

namespace VirtualTest {
    class Program {
        static void Main(string[] args) {
            Person person = new Person();
            Chinese chinese = new Chinese();
            Japanese japanese = new Japanese();
            Person[] persons = { person , chinese , japanese };
            foreach ( var item in persons ) {
                item.sayHello();
            }
            Console.ReadKey();
        }
    }
    class Person {
        public virtual void sayHello() {
            Console.WriteLine("你好,我是人");
        }
    }
    class Chinese:Person {
        public override void sayHello() {
            Console.WriteLine("你好,我是中国人");
        }
    }
    class Japanese:Person {
        public override void sayHello() {
            Console.WriteLine("八嘎,我是傻逼");
        }
    }
}

    使用 virtual 和override之前 :

    使用 virtual 和override之后 :

 

  ④ abstract 抽象类

    子类实现抽象方法需要加上 override 关键字, 其他语法和 Java 一样

namespace AbstractTest {
    class Program {
        static void Main(string[] args) {
            Bird bird = new Bird();
            Fish fish = new Fish();
            Horse horse = new Horse();
            Animal[] animals = { bird, fish, horse };
            foreach ( var item in animals ) {
                item.move();
            }
            Console.ReadKey();
        }
    }
    abstract class Animal {
        public abstract void move();
    }
    class Bird : Animal {
        public override void move() {
            Console.WriteLine("鸟儿在飞");
        }
    }
    class Fish : Animal {
        public override void move() {
            Console.WriteLine("鱼儿在游");
        }
    }
    class Horse : Animal {
        public override void move() {
            Console.WriteLine("马儿在奔跑");
        }
    }
}

    

 

  ⑤ 访问修饰符

    和 Java 不同的是 , C# 类默认的修饰符是 internal , 属性和方法默认是 private , 并且 C# 要求子类的访问权限不能高于父类 , 重写方法的访问权限必须一致

  ⑥ 工厂设计模式   

namespace FactoryPatternTest {
    public class Program {
        // 简单工厂的核心 : 根据用户输入把对象赋值给父类
        public static void Main(string[] args) {
            Console.Clear();
            Console.WriteLine("请输入你需要的笔记本品牌");
            GetNotebook(Console.ReadLine()).sayHello();
            Console.ReadKey(false);
        }
        public static Notebook GetNotebook(string name) {
            Notebook notebook = null;
            switch ( name ) {
                case "戴尔":
                    notebook = new DaiEr();
                    break;
                case "联想":
                    notebook = new LianXiang();
                    break;
                case "华硕":
                    notebook = new HuaShuo();
                    break;
            }
            return notebook;
        }
    }
    public abstract class Notebook {
        public abstract void sayHello();
    }
    public class DaiEr : Notebook {

        public override void sayHello() {
            Console.WriteLine("我是戴尔,我的价格是10000");
        }
    }
    public class LianXiang : Notebook {
        public override void sayHello() {
            Console.WriteLine("我是联想,我的价格是8000");
        }
    }
    public class HuaShuo : Notebook {
        public override void sayHello() {
            Console.WriteLine("我是华硕,我的价格是99999");
        }
    }
}

  ⑦ 值传递和引用传递

    值传递是一种复制传递 , 传递过程中对对象的值进行修改不影响对象本身的值

      

 

    引用传递是传递的对象本身 , 传递过程中对对象的值进行修改影响对象本身的值

      

day7

  ① 序列化和反序列化

/*
 *  序列化 : 把对象转为二进制
 *  反序列化 : 把二进制转为对象
 *  作用 : 传输数据
 *  tips : ① 只有被[Serializable]修饰的类的对象才可以被序列化
 */
namespace 序列化和反序列化 {

    class Program {
        static void Main(string[] args) {
            //序列化
            using ( FileStream fs = new FileStream(@"D:\test\序列化.txt", FileMode.OpenOrCreate, FileAccess.Write) ) {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(fs, new User("1", "张三", ""));
            }
            //反序列化
            using ( FileStream fs = new FileStream(@"D:\test\序列化.txt", FileMode.OpenOrCreate, FileAccess.Read) ) {
                BinaryFormatter bf = new BinaryFormatter();
                object obj= bf.Deserialize(fs);
                Console.WriteLine((User)obj);
            }
            Console.WriteLine("成功");
            Console.ReadKey();
        }
    }
    [Serializable]
    class User {
        private string id;
        private string name;
        private string sex;
        public User(string id, string name, string sex) {
            this.id = id;
            this.name = name;
            this.sex = sex;
        }
        public override string ToString() {
            return "ID:" + id + ", NAME:" + name + ", SEX:" + sex;
        }
    }
}

  ② pertial 部分类

    同一个命名空间下 , 被 pertial 修饰的类可以被允许重复 , 部分类顾名思义就是每个部分类都是类的一部分

  ③ sealed 密封类

    被 sealed 修饰的类不能被继承

  ④ interface 接口类

    命名规范 : public interface I...able

    实现接口类 : 和继承的语法一致 , className : interfaceName

    实现方法的访问权限默认是 private 并且不能被修改 , 其他和 Java 一致

  ⑤ 普通属性和自动属性

class A {
        private string name;
        //普通属性, 需要手动声明字段
        public string Name { get => name; set => name = value; }
        //自动属性, 会自动生成一个私有的字段
        public string Age { get; set; }
    }

  ⑥ MD5 加密

namespace MD5Test {
    class Program {
        static void Main(string[] args) {
            string psw = "123";
            MD5 md5 = MD5.Create();
            byte[] pswByte = Encoding.Default.GetBytes(psw);
            byte[] md5Byte = md5.ComputeHash(pswByte);
            string md5Str = "";
            foreach ( byte b in md5Byte ) {
                md5Str+=b.ToString("x");        //转为16进制的字符串
            }
            Console.WriteLine(md5Str);
            Console.ReadKey();
            }
    }
}

day8

  ① Process 线程类

namespace ProcessTest {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e) {
            /*
             *  打开计算器
             */
            Process.Start("calc");
        }

        private void button2_Click(object sender, EventArgs e) {
            /*
             *  打开test.tet
             */
            ProcessStartInfo psi = new ProcessStartInfo(@"D:\test\txt\test.txt");
            Process process = new Process();
            process.StartInfo = psi;
            process.Start();
        }
    }
}

 

  ② Thread 进程类

    

namespace ThreadTest {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e) {
            //doSome();                   //不启用线程的话要等doSome()执行完毕才能关闭窗口
            Thread t = new Thread(doSome);
            t.IsBackground = true;        //设置这个进程为后台进程(等同于Java中的守护进程)
            t.Start();
            /*
            t.Abort();                  //终止线程
            t.Start();                  //报错,线程终止后不能被重新开启
            */
        }
        private void doSome() {
            //textBox1.Text = "button1被点击了!";   //报错,只能在主线程才能访问到Form控件
            Thread.Sleep(10000);
        }

        private void Form1_Load(object sender, EventArgs e) {
            //Control.CheckForIllegalCrossThreadCalls = false;
            //设置不捕获错误线程的调用,这样其他线程访问Form控件就不会报错
        }
    }
}

 

  ③ Socket 网络编程

/*
 *  Socket 服务端
 */
namespace SocketTest1 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }
        Socket socketSend;
        List<Socket> sockets = new List<Socket>();
        private void button1_Click(object sender, EventArgs e) {
            try {
                //创建一个Socket对象
                Socket socketListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //创建一个IP和端口号对象
                IPEndPoint point = new IPEndPoint(IPAddress.Any, Convert.ToInt32(textBox2.Text));
                //让负责监听的Socket绑定IP和端口号
                socketListen.Bind(point);

                //设置监听队列(同一时间最大连接数)
                socketListen.Listen(3);
                showMsg("监听成功");
                Thread t = new Thread(listen);
                t.IsBackground = true;
                t.Start(socketListen);
            } catch {
                showMsg("监听失败");
            }
            //开启一个线程等待客户端连接
        }
        private void showMsg(string msg) {
            textBox3.AppendText(msg + "\r\n");
        }
        private void listen(object obj) {
            while ( true ) {
                try {
                    Socket socketListen = obj as Socket;
                    socketSend = socketListen.Accept();
                    showMsg(socketSend.RemoteEndPoint.ToString() + "连接成功");
                    sockets.Add(socketSend);
                    comboBox1.Items.Add(socketSend.RemoteEndPoint.ToString());
                    //开启一个线程接收客户端发送的数据
                    Thread t = new Thread(receive);
                    t.IsBackground = true;
                    t.Start(socketSend);
                } catch { }
            }
        }
        //可以不用传参,因为socketSend已经是全局变量了,这里主要是演示一下怎么把有参方法用多线程启动
        private void receive(object obj) {
            while ( true ) {
                try {
                    socketSend = obj as Socket;
                    byte[] buffer = new byte[1024 * 1024];
                    int r = (socketSend as Socket).Receive(buffer);
                    if ( r == 0 ) {
                        break;
                    }
                    string str = Encoding.UTF8.GetString(buffer, 0, r);
                    showMsg(socketSend.RemoteEndPoint.ToString() + ":" + str);
                } catch {
                    showMsg("数据接收失败");
                    break;
                }
            }
        }
        private void Form1_Load(object sender, EventArgs e) {
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        private void button2_Click(object sender, EventArgs e) {
            if ( comboBox1.SelectedIndex == -1 ) {
                MessageBox.Show("请选择发送目标");
            } else {
                byte[] buffer = Encoding.UTF8.GetBytes(textBox4.Text);
                List<byte> bufferList = new List<byte>();
                bufferList.Add(0);
                bufferList.AddRange(buffer);
                try {
                    sockets[comboBox1.SelectedIndex].Send(bufferList.ToArray());
                    showMsg("我:" + textBox4.Text);
                } catch {
                    showMsg("数据发送失败");
                }
            }
        }
        string path;
        private void button3_Click(object sender, EventArgs e) {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = @"D:\test";
            ofd.Title = "选择你要发送的文件";
            ofd.Filter = "全部文件|*.*";
            ofd.ShowDialog();
            path = ofd.FileName;
            if ( path != null && path != "" ) {
                textBox5.Text = path;
            }
        }
        private void button4_Click(object sender, EventArgs e) {
            if ( comboBox1.SelectedIndex == -1 ) {
                MessageBox.Show("请选择发送目标");
            } else if ( path != null && path != "" ) {
                using ( FileStream fsRead = new FileStream(path, FileMode.Open, FileAccess.Read) ) {
                    byte[] buffer = new byte[1024 * 1024];
                    int r = fsRead.Read(buffer, 0, buffer.Length);
                    List<byte> bufferList = new List<byte>();
                    bufferList.Add(1);
                    bufferList.AddRange(buffer);
                    try {
                        sockets[comboBox1.SelectedIndex].Send(bufferList.ToArray(), 0, r + 1, SocketFlags.None);
                        showMsg("文件发送成功");
                    } catch {
                        showMsg("文件发送失败");
                    }
                }
            }
        }
        private void button5_Click(object sender, EventArgs e) {
            if ( comboBox1.SelectedIndex == -1 ) {
                MessageBox.Show("请选择发送目标");
            } else {
                byte[] buffer = new byte[]{ 2 };
                try {
                    sockets[comboBox1.SelectedIndex].Send(buffer);
                    showMsg("震动发送成功");
                } catch {
                    showMsg("震动发送失败");
                }
            }
        }
    }
}

 

/*
 *  Socket客户端
 */
namespace SocketTest2 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }
        Socket socketSend;
        private void button1_Click(object sender, EventArgs e) {
            try {
                socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ip = IPAddress.Parse(textBox1.Text);
                IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(textBox2.Text));
                socketSend.Connect(point);
                showMsg("连接成功");
            } catch {
                showMsg("连接失败");
            }
            //开启一个线程接收服务器发送的数据
            Thread t = new Thread(receive);
            t.IsBackground = true;
            t.Start();
        }
        void showMsg(string msg) {
            textBox3.AppendText(msg + "\r\n");
        }
        private void button2_Click(object sender, EventArgs e) {
            byte[] buffer = Encoding.UTF8.GetBytes(textBox4.Text);
            try {
                socketSend.Send(buffer);
                showMsg("我:" + textBox4.Text);
            } catch {
                showMsg("消息发送失败");
            }
        }
        private void receive(object obj) {
            while ( true ) {
                byte[] buffer = new byte[1024 * 1024];
                try {
                    int r = socketSend.Receive(buffer);
                    if ( r == 0 ) {
                        break;
                    }
                    if ( buffer[0] == 0 ) {
                        string str = Encoding.UTF8.GetString(buffer, 1, r - 1);
                        showMsg(socketSend.RemoteEndPoint.ToString() + ":" + str);
                    } else if ( buffer[0] == 1 ) {
                        SaveFileDialog sfd = new SaveFileDialog();
                        sfd.InitialDirectory = @"D:\test";
                        sfd.Title = "请选择你要保存的路径";
                        sfd.Filter = "所有文件|*.*";
                        sfd.ShowDialog(this);
                        string path = sfd.FileName;
                        if ( path != null && path != "" ) {
                            using ( FileStream fsWrite = new FileStream(path, FileMode.Create, FileAccess.Write) ) {
                                fsWrite.Write(buffer, 1, r - 1);
                                showMsg("文件接收成功");
                            }
                        }
                    } else if ( buffer[0] == 2 ) {
                        for(int i=0;i<500;i++ ) {
                            this.Location = new Point(250, 250);
                            this.Location = new Point(280, 280);
                        }
                    }
                } catch {
                    showMsg("数据接收失败");
                    break;
                }
            }
        }
        private void Form1_Load(object sender, EventArgs e) {
            Control.CheckForIllegalCrossThreadCalls = false;
        }
    }
}

  ④ GDI+ 图形设备接口

 

namespace GDI_Test {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e) {
            //绘制一条直线
            Pen pen = new Pen(Brushes.Red);
            Point p1 = new Point(30, 50);
            Point p2 = new Point(250, 250);
            Graphics g = this.CreateGraphics();
            g.DrawLine(pen, p1, p2);
        }
        private void Form1_Paint(object sender, PaintEventArgs e) {
            //在这里可以当图形被拖出屏幕时,重新绘制图形
        }
        private void button2_Click(object sender, EventArgs e) {
            //绘制一个矩形
            Pen pen = new Pen(Brushes.Red);
            Rectangle rec = new Rectangle(new Point(50, 50), new Size(80, 80));
            Graphics g = this.CreateGraphics();
            g.DrawRectangle(pen, rec);
        }
        private void button3_Click(object sender, EventArgs e) {
            //绘制一个扇形
            Pen pen = new Pen(Brushes.Red);
            Rectangle rec = new Rectangle(new Point(50, 50), new Size(80, 80));
            Graphics g = this.CreateGraphics();
            g.DrawPie(pen, rec, 60, 60);
        }
        private void button4_Click(object sender, EventArgs e) {
            //绘制一个文本
            Graphics g = this.CreateGraphics();
            g.DrawString("文本", new Font("宋体", 20, FontStyle.Underline), Brushes.Black, new Point(200, 200));
        }
        private void button5_Click(object sender, EventArgs e) {
            //绘制一张验证码
            Random r = new Random();
            Bitmap bitmap = new Bitmap(120, 40);
            Graphics g = Graphics.FromImage(bitmap);
            string[] fonts = { "宋体", "微软雅黑", "黑体", "隶书", "仿宋" };
            Color[] colors = { Color.Blue, Color.Black, Color.Red, Color.Green, Color.Gray };
            //
            for ( int i = 0; i < 4; i++ ) {
                Point p = new Point(i * 30, r.Next(0, 10));
                g.DrawString(Convert.ToString(r.Next(0, 10)), new Font(fonts[r.Next(0, 5)], 20, FontStyle.Bold), new SolidBrush(colors[r.Next(0, 5)]), p);
            }
            //线
            for ( int i = 0; i < 10; i++ ) {
                Point p1 = new Point(r.Next(0, bitmap.Width), r.Next(0, bitmap.Height));
                Point p2 = new Point(r.Next(0, bitmap.Width), r.Next(0, bitmap.Height));
                g.DrawLine(new Pen(Brushes.Green), p1, p2);
            }
            //
            for ( int i = 0; i < 500; i++ ) {
                Point p = new Point(r.Next(0, bitmap.Width), r.Next(0, bitmap.Height));
                bitmap.SetPixel(p.X, p.Y,Color.Black);
            }
            pictureBox1.Image = bitmap;
        }
    }
}

 day8

  ① 单例模式

    步骤 : 将构造函数私有化 → 创建一个静态方法返回一个对象 → 创建一个单例对象

 public partial class Form1 : Form {
        private static Form1 form1 = null;
        private Form1() {
            InitializeComponent();
        }
        public Form1 getForm1() {
            if ( form1 == null ) {
                form1 = new Form1();
            }
            return form1;
        }
    }

   ② XML

class Program {
        static void Main(string[] args) {
            //1.创建Xml文档对象
            XmlDocument doc = new XmlDocument();
            //2.创建行描述信息 <?xml version="1.0" encoding="utf-8"?>
            XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "utf-8", null);
            doc.AppendChild(dec);
            //3.创建根节点Books
            XmlElement books = doc.CreateElement("Books");
            doc.AppendChild(books);
            //4.创建Books的子节点Book
            XmlElement book1 = doc.CreateElement("Book");
            books.AppendChild(book1);
            //4.创建Book的子节点Name、Price
            XmlElement name1 = doc.CreateElement("Name");
            name1.InnerText = "三国演义";
            book1.AppendChild(name1);
            XmlElement price1 = doc.CreateElement("Price");
            price1.InnerText = "20";
            book1.AppendChild(price1);
            //5.保存Xml文档
            doc.Save("Books.xml");
            Console.WriteLine("保存成功");
            Console.ReadKey();
        }
    }

  ③ 泛型委托

class Program {
        delegate int DelMax<T>(T t1, T t2);
        static void Main(string[] args) {
            int[] nums = { 1, 564, 8741, 545, 3, 9, 444 };
            int max=Max<int>(nums, compare);
            //string[] strs = { "abc", "defg", "hi", "jklmnopq", "r" };
            //string max = Max<string>(strs, compare);
            Console.WriteLine(max);
            Console.ReadKey();
        }
        static T Max<T>(T[] ts, DelMax<T> dm) {
            T max = ts[0];
            for ( int i = 0; i < ts.Length; i++ ) {
                if ( dm(ts[i], max) > 0 ) {
                    max = ts[i];
                }
            }
            return max;
        }
        static int compare(int num1, int num2) {
            return num1 - num2;
        }
        static int compare(string str1,string str2) {
            return str1.Length - str2.Length;
        }
    }

 

posted @ 2021-04-16 22:48  ianunei1998  阅读(120)  评论(0)    收藏  举报