目录
1.委托
2.匿名方法
3.Action和Func
4.MemoryCache
5.Ref 和 Out
6.扩展方法,关键字this
7.建立NET Standard
8.yield的使用
9.序列化SerializeObject和反序列化DeserializeObject
10.选择一个文件到另一个文件夹中
11.控件跨线程,可以使用CheckForIllegalCrossThreadCalls代替
12.线程回调使用
13.事件传值写法
14.调用委托代替调用方法
15.Task中的ConfigureAwait(false)
16.Select和SelectMany
17.IQueryable和IEnumerable
18.winform中TreeView的遍历
19.winform中DataSource报错问题,点击空格时报错
20.List和HashSet
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
//定义一个委托,不带参数
delegate void Calc();
//定义一个委托,带2个参数
delegate int Calc2(int a, int b);
static void Main(string[] args)
{
Calc c = A; //把A方法赋值给委托c
c(); //调用c
Calc2 c2 = Add; //把A方法赋值给委托c2
c2(1, 2); //调用c2,并且把参数传进去
Calc2 c3 = Minus;
c3(2, 1);
c2 += c3;
c2 -= c3;
// 使用委托对象调用方法
Console.WriteLine("{0}", c2(8, 2));//三个方法都执行了,返回的是最一个值
Console.ReadKey();
}
public static void A()
{
Console.WriteLine("a");
}
public static int Add(int a, int b)
{
Console.WriteLine(a + b);
return a + b;
}
public static int Minus(int a, int b)
{
Console.WriteLine(a - b);
return a - b;
}
}
}
由委托演化而来,变成Lambda表达式
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
//声明委托,带一个参数
delegate void MyDelegate(string s);
//声明委托,不带参数
delegate void MyDelegate1();
static void Main(string[] args)
{
//直接实例化调用
MyDelegate md1 = new MyDelegate(MyMethod);
md1("C#");
//把方法的实现写在一起
MyDelegate md2 = delegate (string s) { Console.WriteLine(s); };
md2("Java");
//把方法的实现写在一起,省略delegate,带参数,演化成Lambda
MyDelegate md3 = (x) => { Console.WriteLine(x); };
md3("Python");
//不带参数,演化成Lambda
MyDelegate1 md4 = () => { m(); };
md4();
Console.ReadKey();
}
static void MyMethod(string s)
{
Console.WriteLine(s);
}
static void m()
{
Console.WriteLine("1");
}
}
}
实际上就是委托
所有的委托表达都可以用Action和Func表示
Action 没有返回值
Func有返回值
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
//声明一个不带参数的Action,Action是没有返回值的
//Action BookAction = new Action(Book);
//BookAction();
//也可以这样写
//Action BookAction = Book;
//BookAction();
//声明一个带2参数的Action,Action是没有返回值的,2个string,都是参数
//Action BookAction2 = new Action(Book2);
//BookAction2("数学", "语文");
//也可以这样写
Action BookAction2 = Book2;
BookAction2("数学", "语文");
//声明一个不带参数的Func,Func是有返回值的,第一个string是返回的类型
//Func BookAction3 = new Func(Book3);
//BookAction3();
//也可以这样写
Func BookAction3 = Book3;
BookAction3();
//声明一个带2个参数的Func,Func是有返回值的,第一个string是返回的类型,后面2个string是参数
//Func BookAction4 = new Func(Book4);
//BookAction4("数学", "语文");
//也可以这样写
Func BookAction4 = Book4;
BookAction4("数学", "语文");
Console.ReadKey();
}
static void Book()
{
Console.WriteLine("数学");
}
static void Book2(string s1, string s2)
{
Console.WriteLine(s1 + s2);
}
static string Book3()
{
return "数学";
}
static string Book4(string s1, string s2)
{
return s1 + s2;
}
}
}
引用:
using System.Runtime.Caching;
创建缓存:
ObjectCache cache = MemoryCache.Default;
缓存中添加值:
cache.Add("CacheName", "Value1", null);
cache.Add("CacheName2", 0, null);
// 创建一个MemoryCache实例
MemoryCache cache = MemoryCache.Default;
// 将数据存储到缓存中
cache["key"] = "value";
// 从缓存中获取数据
string value = (string)cache["key"];
// 清除缓存中的数据
cache.Remove("key");
ref
是有进有出,在使用前必需初始化
out
是只出不进,不需要初始化,初始化也会被清空
using System;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
//string name = "张三";//需要初始化
//RefTest(ref name);
//Console.WriteLine(name);//输出李四
//Console.ReadKey();
string name;//不需要初始化
OutTest(out name);
Console.WriteLine(name);//输出李四
Console.ReadKey();
}
static void RefTest(ref string str)
{
str = "李四";
}
static void OutTest(out string str)
{
str = "李四";
}
}
}
在我们需要多个返回值的时候,就用out,在需要修改修改原先引用的时候用ref
使用扩展方法,可以方便,快捷的向使用系统自带的方法一样
首先,建立一个帮助类,类必须是静态,方法必须是静态,方法的参数必须加上this
public static class Help
{
public static string DataToString(this DateTime dt )
{
return dt.ToString("yyyy-MM--dd");
}
}
使用的时候,在时间类型后直接可以 . 出来。
效果
公共类库创建时,选择NET Standard,可以被.NET Core和老版本的.NET Framework使用。
每次调用时返回一个值,而不是一次性返回所有值。处理大量数据或需要按需生成数据的情况下非常有用。
异步:
static async Task Main(string[] args)
{
await foreach (var item in A())
{
Console.WriteLine(item);
}
}
static async IAsyncEnumerable A()
{
yield return "1";
yield return "2";
yield return "3";
}
同步:
static void Main(string[] args)
{
IEnumerable a = A();
foreach (var item in a)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
static IEnumerable A()
{
yield return "1";
yield return "2";
yield return "3";
}
//实体类
public class user
{
public string id { get; set; }
public string user1 { get; set; }
}
public class Response
{
public int status { get; set; }
public object value { get; set; }
}
DataTable dt = new DataTabl
dt.Columns.Add("id");
dt.Columns.Add("user1");
DataRow dr = dt.NewRow();
dr[0] = "1";
dr[1] = "dangxiaochun";
dt.Rows.Add(dr);
Response rslt = new Response();
rslt.status = 0;
rslt.value = dt;
JsonSerializer serializer = new JsonSerializer();
string json = JsonConvert.SerializeObject(rslt);//序列化
Response rslt1 = JsonConvert.DeserializeObject(json);//反序列化
序列化成类的时候,如果出现大量的修改,可以中间转换一下,再序列化(*)
拓展:
Dictionary dic = JsonConvert.DeserializeObject>(json);
使用Dictionary可以把json反序列化转成字典显示,然后方便处理。
格式如下:
string s = "{\"text\": true,\"index\": 0,\"logprobs\": null,\"finish_reason\": 123}";
var a = JsonConvert.DeserializeObject(s);
string aa = a.text;
效果
if (!Directory.Exists("img\\1"))
{
Directory.CreateDirectory("img\\1");
}
Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog();
dialog.Multiselect = true;
dialog.Filter = "Image(JPG)|*.jpg";
bool? result = dialog.ShowDialog();
if (result.HasValue && result.Value)
{
string dir = dialog.FileNames[0].Replace(dialog.SafeFileNames[0], "");
foreach (string item in dialog.SafeFileNames)
{
File.Copy(dir + item, AppDomain.CurrentDomain.BaseDirectory + @"img\1\" + item);
}
}
适用于winform
//Invoke(new Action(() => textBox2.Text = str));
CheckForIllegalCrossThreadCalls = false;
textBox2.Text = str;
主窗体调用后,又回到主窗体中。
//在一个类中
private void DataChange_Callback(string pDataNode, string pVersion, string pDataContent)
{}
udpThread = new Thread(()=>ReciveMsg(client, DataChange_Callback));
udpThread.Start();
//在另一个类中
public static void ReciveMsg(UdpClient client, DataChangeCallback callback)
{
client = new UdpClient(new IPEndPoint(IPAddress.Any, 4567));
IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
try
{
if (client.Available <= 0) continue;
if (client.Client == null) return;
byte[] bytes = client.Receive(ref iPEndPoint);
string str = Encoding.Default.GetString(bytes);
Console.WriteLine(str);
callback(str.Split('|')[0], str.Split('|')[1], str.Split('|')[2]);
}
catch (Exception)
{
throw;
}
}
public delegate void DataChangeCallback(string pDataNode, string version, string pDataContent);
第一种
public static void TimerFun(string str)
{
DispatcherTimer createIconTimer = new DispatcherTimer();
createIconTimer.Tick += (s, e) =>
{
Consolo.WriteLine(str);
}; createIconTimer.Interval = new TimeSpan(0, 0, 3); createIconTimer.Start(); //3秒
}
第二种
private System.Timers.Timer aTimer;
public void TimerFun(string str)
{
aTimer = new System.Timers.Timer(600000); //10分钟 600000
aTimer.Elapsed += new ElapsedEventHandler((s, e) => OnTimedEvent(s, e, str));
aTimer.Interval = 60000;
aTimer.Enabled = true;
aTimer.AutoReset = false;
}
private static void OnTimedEvent(object source, ElapsedEventArgs e, string str)
{
Console.WriteLine(str);
}
意思就是,以调用委托的方式来代替调用方法来执行
using System;
using System.Collections.Generic;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
//A(); //通常使用
Action action = A;
action.Invoke(); //委托使用
}
static void A()
{
Console.WriteLine("Hello World!");
}
}
}
async Task WaitAsync()
{
// 这里 awati 会捕获当前上下文……
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
// ……这里会试图用上面捕获的上下文继续执行
}
void Deadlock()
{
// 开始延迟
Task task = WaitAsync();
// 同步程序块,正在等待异步方法完成
task.Wait();
}
调用
private void button1_Click(object sender, EventArgs e)
{
Deadlock();
}
这个难度有点大,反正没看懂。
上面的这个例子说明,如果加了.ConfigureAwait(false)就不会死锁,不加的话,就会,参考这个网址。
理解C#中的ConfigureAwait - xiaoxiaotank - 博客园
提示:不要用 void 作为 async 方法的返回类型! async 方法可以返回 void,但是这
仅限于编写事件处理程序。 一个普通的 async 方法如果没有返回值,要返回
Task,而不是 void
在使用Select时,如果遇到循环值的问题,可以使用SelectMany代替,代码简单一层。
string[] a = { "aa","bb", "cc", "dd", "ee","ff" };
var a1 = a.Select(a => a.Split("")); //也可以写成' '
foreach (var item in a1)
{
foreach (var item1 in item)
{
Console.WriteLine(item1);
}
}
var a2 = a.SelectMany(a => a.Split(' '));
foreach (var item in a2)
{
Console.WriteLine(item);
}
效果
IEnumerable:该枚举器支持在指定类型的集合上进行简单迭代。一次性把数据加载在内存中,直接访问数据库,然后再使用。
IQueryable:它继承 IEnumerable 接口。不是把数据一次性加载在内存中,而是使用它的时候再去访问数据库调用,把具体数据加载内存中。
List ls = new List();
ls.Add(1);
ls.Add(2);
ls.Add(3);
ls.Add(4);
ls.Add(5);
IQueryable iq = (from c in ls
select c).AsQueryable();
IEnumerable ie = (from c in ls
select c).AsEnumerable();
List listNodes = new List();
SetTreeViewList(treeOPCNode.Nodes, ref listNodes);
public void SetTreeViewList(TreeNodeCollection nodes, ref List listNodes)
{
//if (nodes!=null)
//{
// listNodes.Add(new OPCNodeModel(nodes.Name, nodes.Text));
//}
//有子节点
foreach (TreeNode newNode in nodes)
{
if (newNode.Level == 0)
{
listNodes.Add(new OPCNodeModel(newNode.Name, newNode.Text, "0"));
}
else
{
listNodes.Add(new OPCNodeModel(newNode.Name, newNode.Text, newNode.Parent.Name));
}
if (newNode.Nodes.Count > 0)
{
SetTreeViewList(newNode.Nodes, ref listNodes);
}
}
}
先关闭列自动,屏蔽初始化数据的值,使用的地方重新赋值
gcDiscover.AutoGenerateColumns = false;
//this.gcDiscover.DataSource = this.findUrls;
gcDiscover.DataSource = null;
gcDiscover.DataSource = findUrls;
数量非常大的时候,使用HashSet比使用List速度要快的多,使用方法是一样的,但是他们的时间复杂度不一样。追求性能优选HashSet。
List list = new List() { 1, 2, 3, 4, 5, 6, 7 }; //时间复杂度O(n)
HashSet hashSet = new HashSet() { 1, 2, 3, 4, 5, 6, 7 }; //时间复杂度O(1)
list.Contains(1);
hashSet.Contains(1);
来源:记录C#知识点(一)1-20_c# serializeobject-CSDN博客