记录C#知识点(一)1-20

目录

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 


1.委托

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;
        }
    }
}

2.匿名方法

由委托演化而来,变成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");
        }
    }
}

3.Action和Func

实际上就是委托

所有的委托表达都可以用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;
        }
    }
}

4.MemoryCache

引用:

using System.Runtime.Caching;

创建缓存:

ObjectCache cache = MemoryCache.Default;  

缓存中添加值:

cache.Add("CacheName", "Value1", null);
cache.Add("CacheName2", 0, null);

记录C#知识点(一)1-20_第1张图片

            // 创建一个MemoryCache实例
            MemoryCache cache = MemoryCache.Default;
 
            // 将数据存储到缓存中
            cache["key"] = "value";
 
            // 从缓存中获取数据
            string value = (string)cache["key"];
 
            // 清除缓存中的数据
            cache.Remove("key");

5.Ref 和 Out

 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

6.扩展方法,关键字this

使用扩展方法,可以方便,快捷的向使用系统自带的方法一样

首先,建立一个帮助类,类必须是静态,方法必须是静态,方法的参数必须加上this

   public static class Help
    {
        public static string DataToString(this DateTime dt )
        {
            return dt.ToString("yyyy-MM--dd");
        }
    }

使用的时候,在时间类型后直接可以 . 出来。

记录C#知识点(一)1-20_第2张图片

效果 

记录C#知识点(一)1-20_第3张图片

7.建立NET Standard

公共类库创建时,选择NET Standard,可以被.NET Core和老版本的.NET Framework使用。

8.yield的使用

每次调用时返回一个值,而不是一次性返回所有值。处理大量数据或需要按需生成数据的情况下非常有用。

异步:

        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";
        }

9.序列化SerializeObject和反序列化DeserializeObject

//实体类
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反序列化转成字典显示,然后方便处理。

格式如下:

记录C#知识点(一)1-20_第4张图片

string s = "{\"text\": true,\"index\": 0,\"logprobs\": null,\"finish_reason\": 123}";
            var a = JsonConvert.DeserializeObject(s);
            string aa = a.text;

效果 

10.选择一个文件到另一个文件夹中 

  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);
                }
            }

11.控件跨线程,可以使用CheckForIllegalCrossThreadCalls代替

适用于winform

 //Invoke(new Action(() => textBox2.Text = str));

CheckForIllegalCrossThreadCalls = false;

textBox2.Text = str;

12.线程回调使用

主窗体调用后,又回到主窗体中。

//在一个类中  
 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);

13.事件传值写法

第一种

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);          
}

14.调用委托代替调用方法

意思就是,以调用委托的方式来代替调用方法来执行

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!");
        }
    }
}

15.Task中的ConfigureAwait(false)

        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

16.Select和SelectMany

在使用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);
            }

效果

记录C#知识点(一)1-20_第5张图片

17.IQueryable和IEnumerable

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();

18.winform中TreeView的遍历

  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);
                }
            }
        }

19.winform中DataSource报错问题,点击空格时报错

先关闭列自动,屏蔽初始化数据的值,使用的地方重新赋值

 gcDiscover.AutoGenerateColumns = false;

//this.gcDiscover.DataSource = this.findUrls;

gcDiscover.DataSource = null;
gcDiscover.DataSource = findUrls;

20.List和HashSet 

数量非常大的时候,使用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博客

你可能感兴趣的:(记录(持续更新),c#,开发语言)