单例模式
抛砖引玉
例如QQ应用程序,每次打开QQ,则创建新的登陆窗口,可以登录多个账号。而FeiQ,每次打开都是相同的窗口。
含义
一个类只允许创建一个对象。
步骤
- 将构造函数私有化
- 提供一个静态方法,返回一个对象
- 创建一个单例
public partial class Form2 : Form { public static Form2 FrmSingle = null; private Form2() { InitializeComponent(); } public static Form2 GetSingle() { if(FrmSingle == null) { FrmSingle = new Form2(); } return FrmSingle; } }
|
创建单例代码
private void button1_Click(object sender, EventArgs e) { Form2 frm2 = Form2.GetSingle(); frm2.Show(); }
|
XML
概念
xml:可扩展标记语言,用于存储数据。
节点:一个个的标签称为节点。
元素:XML文档中的所有内容。
注意:
- XML严格区分大小写
- XML标签是成对出现的
- XML文档有且仅有一个根节点
通过代码来创建XML文档
XmlDocument doc = new XmlDocument();
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "utf-8", null); doc.AppendChild(dec);
XmlElement books = doc.CreateElement("Books");
doc.AppendChild(books);
XmlElement book1 = doc.CreateElement("Book");
books.AppendChild(book1);
XmlElement name1 = doc.CreateElement("Name"); name1.InnerText = "金瓶梅"; book1.AppendChild(name1);
XmlElement price1 = doc.CreateElement("Price"); price1.InnerText = "10"; book1.AppendChild(price1);
XmlElement des1 = doc.CreateElement("Des"); des1.InnerText = "好看"; book1.AppendChild(des1);
doc.Save("Books.xml"); Console.WriteLine("保存成功"); Console.ReadKey();
|
创建带属性的XML文档
XmlDocument doc = new XmlDocument(); XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "utf-8", null); doc.AppendChild(dec);
XmlElement order = doc.CreateElement("Order"); doc.AppendChild(order);
XmlElement customerName = doc.CreateElement("CustomerName"); customerName.InnerText = "张三"; order.AppendChild(customerName);
XmlElement customerNumber = doc.CreateElement("CustomerNumber"); customerNumber.InnerText = "1000001"; order.AppendChild(customerNumber);
XmlElement items = doc.CreateElement("Items"); order.AppendChild(items);
XmlElement orderItem1 = doc.CreateElement("OrderItem");
orderItem1.SetAttribute("Name", "姓名1"); orderItem1.SetAttribute("Count", "10"); items.AppendChild(orderItem1);
doc.Save("Order.xml"); Console.WtiteLine("保存成功"); Console.ReadKey();
|
注意:
InnerXml和InnerText的区别。添加标签时使用InnerXml,如customerName.InnerXml = “<p>我是一个p标签</p>”。添加文本时使用InnerText,如customerNumber.InnerText = “100001”。
追加XML
XmlDocument doc = new XmlDocument(); if(File.Exist("Books.xml")) { doc.Load("Books.xml"); XmlElement books = doc.DocumentElement; } else { XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "utf-8", null); doc.AppendChild(dec); XmlElement books = doc.CreateElement("Books"); doc.AppendChild(books); }
XmlElement book1 = doc.CreateElement("Book");
books.AppendChild(book1);
XmlElement name1 = doc.CreateElement("Name"); name1.InnerText = "C#开发大全"; book1.AppendChild(name1);
XmlElement price1 = doc.CreateElement("Price"); price1.InnerText = "110"; book1.AppendChild(price1);
XmlElement des1 = doc.CreateElement("Des"); des1.InnerText = "看不懂"; book1.AppendChild(des1);
doc.Save("Books.xml"); Console.WriteLine("保存成功"); Console.ReadKey();
|
读取XML文档
XmlDocument doc = new XmlDocument();
doc.Load("Books.xml");
XmlElement books = doc.DocumentElement;
XmlNodeList xnl = books.ChildNodes;
foreach (XmlNode item in xnl) { Console.WriteLine(item.InnerText); } Console.ReadKey();
|
读取带属性的XMl文档
XmlDocument doc = new XmlDocument(); doc.Load("Order.xml"); XmlNodeList xnl = doc.SelectNodes("/Order/Items/OrderItem");
foreach (XmlNode item in xnl) { Console.WriteLine(node.Attribute["Name"].Value); Console.WriteLine(node.Attribute["Count"].Value); } Console.ReadKey();
|
删除节点
XmlDocument doc = new XmlDocument(); doc.Load("Order.xml");
XmlNode xn = doc.SelectSingleNode("/Order/Items"); xn.RemoveAll(); doc.Save("Order.xml"); Console.WriteLine("删除成功"); Console.ReadKey();
|
委托
为什么要使用委托
将一个方法作为参数传递给另一个方法。
概念
声明一个委托指向一个函数,委托所指向的函数必须跟委托具有相同的签名(返回值和参数)。
委托语法
声明一个委托
public delegate void DelSayHi(string name);
|
调用委托
DelSayHi del = new DelSayHi(SayHiChinese);
del("张三");
|
注意:DelSayHi del = new DelSayHi(SayHiChinese)可以替换为DelSayHi del = SayHiChinese。
将委托作为参数传递给一个方法
public delegate void DelSayHi(string name);
static void Main(string[] args) { Test("张三", SayHiChinese); Test("Zhangsan", SayHiEnglish); Console.ReadKey(); }
public static void Test(string name, DelSayHi del) { del(name); }
public static void SayHiChinese(string name) { Console.WriteLine("你好" + name); }
public static void SayHiEnglish(string name) { Console.WriteLine("Nice to meet you " + name); }
|
匿名函数
概念
没有名称,只有方法体,通常只调用一次。
语法
public delegate void DelSayHi(string name);
static void main(string[] args) { DelSayHi del = delegate (string name) { Console.WriteLine("你好" + name); }; del("张三"); Console.ReadKey(); }
|
泛型委托
使用泛型委托,实现求任意类型数组的最大值。
声明泛型委托
public delegate int DelCompare<T>(T t1, T t2);
|
Main方法
static void Main(string[] args) { int[] nums = { 1, 2, 3, 4, 5 }; int max = GetMax<int>(nums, Compare1); Console.WriteLine(max);
string[] names = { "sdaf", "fgklbhjkjbckbh", "fds" }; string max1 = GetMax<string>(names, (string s1, string s2) => { return s1.Length - s2.Length; }); Console.WriteLine(max1); Console.ReadKey(); }
|
泛型委托求数组最大值
public static T GetMax<T>(T[] nums, DelCompare<T> del) { T max = nums[0]; for (int i = 0; i < nums.Length; i++) { if (del(max, nums[i]) < 0) { max = nums[i]; } } return max; }
|
委托指向的函数
public static int Compare1(int n1, int n2) { return n1 - n2; }
|
lambda表达式
lambda表达式的本质是匿名函数,lambda表达式比匿名函数更加简单。
定义三个签名不同的委托
public delegate void DelOne(); public delegate void DelTwo(string name); public delegate string DelThree(string name);
|
分别使用匿名函数和lambda表达式
DelOne del1 = () => { };
DelTwo del2 = (string name) => { };
DelThree del3 = (string name) => { return name; };
|
lambda表达式在需要委托参数的方法中的应用
List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; list.RemoveAll(n => n > 4); foreach (var item in list) { Console.WriteLine(item); }
|
多播委托
即委托不仅可以指向一个函数,它可以指向多个函数。
首先声明一个委托
public delegate void DelTest();
|
委托指向多个函数
static void main(string[] args) { DelTest del = T1; del += T2; del += T3; del(); Console.ReadKey(); }
public static void T1() { Console.WriteLine("我是T1"); }
public static void T2() { Console.WriteLine("我是T2"); }
public static void T3() { Console.WriteLine("我是T3"); }
|