<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>C# on LiuYingbo Blog</title><link>https://liuyingbo.com/tags/c%23/</link><description>Recent content in C# on LiuYingbo Blog</description><generator>Hugo -- 0.160.0</generator><language>zh-cn</language><lastBuildDate>Thu, 24 Nov 2022 22:49:16 +0000</lastBuildDate><atom:link href="https://liuyingbo.com/tags/c%23/index.xml" rel="self" type="application/rss+xml"/><item><title>C# LINQ</title><link>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c-linq/</link><pubDate>Thu, 24 Nov 2022 22:49:16 +0000</pubDate><guid>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c-linq/</guid><description>&lt;p&gt;LINQ 是 Language INtegrated Query 单词的首字母缩写，翻译过来是语言集成查询。它为查询跨各种数据源和格式的数据提供了一致的模型，所以叫集成查询。由于这种查询并没有制造新的语言而只是在现有的语言基础上来实现，所以叫语言集成查询。&lt;/p&gt;
&lt;h2 id="基础"&gt;基础&lt;/h2&gt;
&lt;p&gt;在 C# 中，从功能上 LINQ 可分为两类：LINQ to Object 和 LINQ to XML；从语法上 LINQ 可以分为 LINQ to Object 和 LINQ 扩展方法&lt;/p&gt;
&lt;p&gt;纠正：&lt;/p&gt;
&lt;p&gt;从功能上 LINQ 可分为两类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LINQ to Object，查询内存集合，直接把查询编译成 .NET 代码执行。&lt;/li&gt;
&lt;li&gt;LINQ to Provider，查询自定义数据源，由开发者提供相应数据源的 Provider 并翻译和执行自定义查询，如 XML、JSON 等都可以作为 Provider 对应的数据源，数据源对应的 LINQ 查询叫 LINQ to &amp;lt;数据源&amp;gt;，比如：LINQ to XML。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;从语法上 LINQ 可以分为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SQL风格：语法和 SQL 相似，部分复杂查询用 SQL 风格语义会更清晰明了，比如 SelectMany 和 Join 查询。SQL 风格的可读性有绝对优势，但不支持全部标准 LINQ 函数，不支持自定义函数。纯粹的语法糖。&lt;/li&gt;
&lt;li&gt;函数风格：以 C# 扩展方法的方式实现，扩展方法即可以是标准库提供的也可以是自己实现的，完全的原生编程风格，编译后的代码都是函数调用。支持全部标准 LINQ 函数和任何自定义函数。随着查询复杂度的提高，可读性不如 SQL 风格。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;感谢 @coredx 的纠正。&lt;/p&gt;</description></item><item><title>C#数据结构与算法</title><link>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/</link><pubDate>Thu, 10 Feb 2022 22:17:46 +0000</pubDate><guid>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/</guid><description>&lt;h2 id="数据结构与算法"&gt;数据结构与算法&lt;/h2&gt;
&lt;h3 id="什么是数据结构与算法"&gt;什么是数据结构与算法？&lt;/h3&gt;
&lt;p&gt;在学习数据结构与算法的时候，常常会思考一个问题：什么是数据结构与算法？&lt;/p&gt;
&lt;p&gt;这里比较找到了一个比较好的答案。&lt;/p&gt;
&lt;p&gt;从宏观来讲：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据结构是一组数据的存储结构。&lt;/li&gt;
&lt;li&gt;算法就是操作数据的方法。&lt;/li&gt;
&lt;li&gt;数据结构为算法服务，算法要作用在特定的数据结构中。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;从狭义上来讲，就是数据结构与算法这门学科就是去学习比较经典的数据结构和算法。&lt;/p&gt;
&lt;p&gt;有点像学习设计模式一样，学习 23 种设计模式。&lt;/p&gt;
&lt;h3 id="如何学习数据结构与算法"&gt;如何学习数据结构与算法？&lt;/h3&gt;
&lt;p&gt;说到设计模式，学习数据结构与算法与学习设计模式非常相似的。&lt;/p&gt;
&lt;p&gt;我们知道设计模式有 23 种，而一般一个开发者学习设计模式的时候，往往会对 23 个设计模式都从头到尾学一遍，但是学完之后发现除了记了个名字之外没啥卵用，就连名字也不一定记得住。&lt;/p&gt;
&lt;p&gt;那么是以为 23 种设计模式的核心并不是设计模式本身，而是 23 种设计模式所遵循的 SOLID 原则，即六大设计原则，而开发者一开始最应该掌握的是六大设计原则，而不是设计模式，六大设计原则是核心，而 23 种设计模式算是 23 种对于六大设计原则的案例一样，一定要先搞清楚这一点。否则学习就会事倍功半，当然如果有一定的编码经验再去学设计模式更好一些。&lt;/p&gt;
&lt;p&gt;学习数据结构与算法也是一样的，数据结构与算法的核心是时间复杂度和空间复杂度，就像对于设计模式中的六大设计原则一样，掌握了时间复杂度和空间复杂度的评估，那么剩下的经典的常用的数据结构和算法就是一个个案例而已，而不用死记硬背，当然有一定的编码经验再去学习会更好一些。&lt;/p&gt;
&lt;p&gt;这就是数据结构与算法的学习思路。&lt;/p&gt;
&lt;h3 id="为什么要学习数据结构与算法"&gt;为什么要学习数据结构与算法？&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;国内大厂的面试比较爱考，但是考得不是很难&lt;/li&gt;
&lt;li&gt;Google、Facebook、微软等更爱考，而且非常难。&lt;/li&gt;
&lt;li&gt;可以评估代码性能，写出高性能的代码&lt;/li&gt;
&lt;li&gt;开发时选择合适的数据结构&lt;/li&gt;
&lt;li&gt;比较有名的基础框架，都柔和了很多基础数据解耦股和算法的设计思想&lt;/li&gt;
&lt;li&gt;阅读源码的时候可以减少阻碍（比如遇到一些算法的实现）&lt;/li&gt;
&lt;li&gt;提高编程能力&lt;/li&gt;
&lt;li&gt;思维提升&lt;/li&gt;
&lt;li&gt;简历上可以写一个精通数据结构与算法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="数据结构与算法是不是高智商开发者的专属"&gt;数据结构与算法是不是高智商开发者的专属？&lt;/h3&gt;
&lt;p&gt;当然不是，数据结构与算法的常用的知识点不多，而且也不需要高智商。重点还是熟能生巧。&lt;/p&gt;
&lt;h3 id="数据结构与算法学科的解决问题重点是什么"&gt;数据结构与算法学科的解决问题重点是什么？&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;更省更快地存储和处理数据的问题
&lt;img alt="image.png" loading="lazy" src="https://blog-1308267163.cos.ap-shanghai.myqcloud.com/imgs/202211191923357.png"&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="时间复杂度"&gt;时间复杂度&lt;/h3&gt;
&lt;p&gt;时间复杂度的定义很简单：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;算法的执行时间与数据规模之间的增长关系&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;时间复杂度的全称其实叫做：渐进时间复杂度，我们就叫时间复杂度即可。&lt;/p&gt;
&lt;p&gt;时间复杂度的定义难得的清晰，不像一些设计模式这样的定义非常抽象。&lt;/p&gt;
&lt;p&gt;OK，既然时间复杂度的定义这么简单，那么我们也顺便说一下空间复杂度吧，空间复杂度的定义如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;算法的存储空间与数据规模之间的增长关系。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;空间复杂度的定义也非常直白。&lt;/p&gt;
&lt;p&gt;List 的遍历，代码如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(){&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;c&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;代码中的 list 的数据规模是 3，其实就是数据量，那么这一段代码所执行的时间就是， Debug.Log(s) 所执行的时间 x 3。&lt;/p&gt;</description></item><item><title>Unity协程</title><link>https://liuyingbo.com/posts/unity/unity%E6%90%BA%E7%A8%8B/</link><pubDate>Wed, 09 Feb 2022 22:49:20 +0800</pubDate><guid>https://liuyingbo.com/posts/unity/unity%E6%90%BA%E7%A8%8B/</guid><description>&lt;h2 id="yield"&gt;yield&lt;/h2&gt;
&lt;p&gt;yield 实质是一个语法糖，它让程序员能够更方便的去使用迭代器，通过 yield 你可以直接使用迭代器操作而不需要去实现 IEnumerable 和 IEnumerator，也不需要一个临时的 Collection 来完成迭代。&lt;/p&gt;
&lt;p&gt;yield 有两种格式声明&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;yield return &amp;lt;expression&amp;gt;;
yield break;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;using System.Collections;
using UnityEngine;
namespace UniRxLesson
{
public class YieldExample : MonoBehaviour
{
private void Start()
{
foreach (var empty in FiveTimes())
{
Debug.Log(&amp;#34;A&amp;#34;);
}
}
private IEnumerable FiveTimes()
{
for (var i = 0; i &amp;lt; 5; i++)
{
yield return string.Empty;
}
}
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;输出结果为&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;A
A
A
A
A
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;每一次 foreach 的循环中都会调用迭代器方法，当 yield return 被执行到时，表达式的值会被返回，同时当前的函数的上下文信息被保存下来。下一次循环执行之时会重新从上一次停止的位置继续执行。你也可以使用 yield break 来终止迭代过程。&lt;/p&gt;</description></item><item><title>c# async/await</title><link>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c%23%E5%AD%A6%E4%B9%A0-async-await/</link><pubDate>Sun, 05 Dec 2021 21:29:02 +0000</pubDate><guid>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c%23%E5%AD%A6%E4%B9%A0-async-await/</guid><description>&lt;p&gt;Talk is cheap, Show you the code first！&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;button1_Click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;111 balabala. My Thread ID is :&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentThread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ManagedThreadId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AsyncMethod&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;222 balabala. My Thread ID is :&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentThread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ManagedThreadId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="n"&gt;AsyncMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ResultFromTimeConsumingMethod&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TimeConsumingMethod&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ResultFromTimeConsumingMethod&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; + AsyncMethod. My Thread ID is :&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentThread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ManagedThreadId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//返回值是Task的函数可以不用return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//这个函数就是一个耗时函数，可能是IO操作，也可能是cpu密集型工作。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;TimeConsumingMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Helo I am TimeConsumingMethod. My Thread ID is :&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentThread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ManagedThreadId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Helo I am TimeConsumingMethod after Sleep(5000). My Thread ID is :&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentThread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ManagedThreadId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Hello I am TimeConsumingMethod&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="异步方法的结构"&gt;异步方法的结构&lt;/h2&gt;
&lt;p&gt;上面是一个的使用&lt;code&gt;async/await&lt;/code&gt;的例子（为了方便解说原理我才写的这样复杂的）。
使用&lt;code&gt;async/await&lt;/code&gt;能非常简单的创建异步方法，防止耗时操作阻塞当前线程。
使用&lt;code&gt;async/await&lt;/code&gt;来构建的异步方法，逻辑上主要有下面三个结构：&lt;/p&gt;</description></item><item><title>C#反射机制</title><link>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c%23-%E5%8F%8D%E5%B0%84%E6%9C%BA%E5%88%B6/</link><pubDate>Sun, 05 Dec 2021 21:26:10 +0000</pubDate><guid>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c%23-%E5%8F%8D%E5%B0%84%E6%9C%BA%E5%88%B6/</guid><description>&lt;h2 id="c反射机制"&gt;C#反射机制&lt;/h2&gt;
&lt;p&gt;资料转载自知乎:https://zhuanlan.zhihu.com/p/41282759&lt;/p&gt;
&lt;h3 id="何为反射"&gt;&lt;strong&gt;何为反射?&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;首先我们通过两个实例来说明反射的大体概念。&lt;/p&gt;
&lt;p&gt;B超:大家体检的时候大概都做过B超,B超可以透过肚皮探测到你内脏的生理情况。这是如何做到的呢?B超是B型超声波,它可以透过肚皮通过向你体内发射B型超声波,当超声波遇到内脏壁的时候就会产生一定的“回音”反射,然后把“回音”进行处理就可以显示出内脏的情况了。&lt;/p&gt;
&lt;p&gt;地球内部结构:地球的内部结构大体可以分为三层:地壳、地幔和地核。如何在地球表面不用深入地球内部就知道其内部的构造呢?我们可以向地球发射“地震波”,“地震波”分两种一种是“横波”,另一种是“纵波”。“横波”只能穿透固体,而“纵波”既可穿透固体又可以穿透液体。通过在地面对纵波和横波的反回情况,我们就可以大体断定地球内部的构造了。&lt;/p&gt;
&lt;p&gt;大家注意到这两个例子的共同特点,就是从一个对象的外部去了解对象内部的构造,而且都是利用了波的反射功能。在.NET中的反射也可以实现从对象的外部来了解对象(或程序集)内部结构的功能,哪怕你不知道这个对象(或程序集)是个什么东西,另外.NET中的反射还可以运态创建出对象并执行它其中的方法。&lt;/p&gt;
&lt;p&gt;反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类、结构、委托、接口和枚举等)的成员和成员的信息。有了反射,即可对每一个类型了如指掌。另外我还可以直接创建对象,即使这个对象的类型在编译时还不知道。&lt;/p&gt;
&lt;p&gt;为什么使用反射,而不直接引用它的dll或者类型呢?&lt;/p&gt;
&lt;p&gt;例如你有个main.exe,需要使用say.dll,draw.dll,突然客户说我们要添加一个跑的功能,那么只需要按照我们约定的规则做一个run的dll,之前的main.exe不需要做任何修改(就是不需要再去导入run.dll,其中需要其他的设计来规范),在main.exe中就能直接使用run.dll了。&lt;/p&gt;
&lt;p&gt;其实,我们已经在不自觉地使用它了,举个最简单的例子,当你在VS的设计器里拖入一个控件后,设计器会通过反射获取这个控件的属性,并提供你进行设置。那么,问题来了,为什么要用反射呢?因为设计器在做的时候,根本不可能预知将来有什么控件会被你拖入进去。&lt;/p&gt;
&lt;h3 id="反射的用途简要介绍"&gt;&lt;strong&gt;反射的用途简要介绍&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;反射的用途大体总结如下,我们会在下面详细的进行介绍。
(1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。
(2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
(3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。
(4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。
(5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
(6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序
(7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。
(8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。&lt;/p&gt;
&lt;p&gt;反射用到的主要类:&lt;/p&gt;
&lt;p&gt;System.Type 类&amp;ndash;通过这个类可以访问任何给定数据类型的信息。
System.Reflection.Assembly类&amp;ndash;它可以用于访问给定程序集的信息,或者把这个程序集加载到程序中。
System.Type类:System.Type 类对于反射起着核心的作用。但它是一个抽象的基类,Type有与每种数据类型对应的派生类,我们使用这个派生类的对象的方法、字段、属性来查找有关该类型的所有信息。获取给定类型的Type引用有3种常用方式:&lt;/p&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="https://blog-1308267163.cos.ap-shanghai.myqcloud.com/imgs/202211191924905.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="https://blog-1308267163.cos.ap-shanghai.myqcloud.com/imgs/202211191924797.jpg"&gt;&lt;/p&gt;
&lt;h3 id="type类的属性"&gt;&lt;strong&gt;Type类的属性:&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Name 数据类型名&lt;/p&gt;
&lt;p&gt;FullName 数据类型的完全限定名(包括命名空间名)
Namespace 定义数据类型的命名空间名
IsAbstract 指示该类型是否是抽象类型&lt;/p&gt;
&lt;p&gt;IsArray 指示该类型是否是数组&lt;/p&gt;
&lt;p&gt;IsClass 指示该类型是否是类
IsEnum 指示该类型是否是枚举
IsInterface 指示该类型是否是接口
IsPublic 指示该类型是否是公有的
IsSealed 指示该类型是否是密封类
IsValueType 指示该类型是否是值类型&lt;/p&gt;
&lt;h3 id="type类的方法"&gt;&lt;strong&gt;Type类的方法:&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;GetConstructor(), GetConstructors():返回
ConstructorInfo类型,用于取得该类的构造函数的信息
GetEvent(), GetEvents():返回EventInfo类型,用于取得该类的事件的信息
GetField(), GetFields():返回FieldInfo类型,用于取得该类的字段(成员变量)的信息
GetInterface(), GetInterfaces():返回InterfaceInfo类型,用于取得该类实现的接口的信息
GetMember(), GetMembers():返回MemberInfo类型,用于取得该类的所有成员的信息
GetMethod(), GetMethods():返回MethodInfo类型,用于取得该类的方法的信息
GetProperty(), GetProperties():返回PropertyInfo类型,用于取得该类的属性的信息可以调用这些成员,其方式是调用Type的InvokeMember()方法,或者调用MethodInfo, PropertyInfo和其他类的Invoke()方法。&lt;/p&gt;</description></item><item><title>C#学习-C# 3.0</title><link>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c%23%E5%AD%A6%E4%B9%A0-c%23-3.0/</link><pubDate>Sun, 05 Dec 2021 21:01:21 +0000</pubDate><guid>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c%23%E5%AD%A6%E4%B9%A0-c%23-3.0/</guid><description>&lt;h2 id="c-30-版本"&gt;C# 3.0 版本&lt;/h2&gt;
&lt;p&gt;C# 3.0 新增的语法特性，如下:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自动实现的属性&lt;/li&gt;
&lt;li&gt;匿名类型&lt;/li&gt;
&lt;li&gt;查询表达式（LINQ）&lt;/li&gt;
&lt;li&gt;表达式&lt;/li&gt;
&lt;li&gt;表达式树&lt;/li&gt;
&lt;li&gt;扩展方法&lt;/li&gt;
&lt;li&gt;隐式类型本地变量&lt;/li&gt;
&lt;li&gt;分部方法&lt;/li&gt;
&lt;li&gt;对象和集合初始值设定项&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="自动实现属性"&gt;自动实现属性&lt;/h2&gt;
&lt;p&gt;这个特性非常简单，代码如下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PropertyExample&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// C# 3.0之前&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;mNickName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;NickName&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;mNickName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;mNickName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// C# 3.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;非常简单，看代码就懂了。&lt;/p&gt;
&lt;h2 id="匿名类型"&gt;匿名类型&lt;/h2&gt;
&lt;p&gt;代码也很简单，如下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="lambda-表达式"&gt;lambda 表达式&lt;/h2&gt;
&lt;p&gt;lambda 表达式非常简单，就是匿名方法的一种表现，如下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LambdaExpressionExample&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// C# 1.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;action1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// C# 2.0 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;actionB&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;delegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// C# 3.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;acionC&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="表达式树"&gt;表达式树&lt;/h2&gt;
&lt;p&gt;表达式树实际上是 Expression 这个 API 的使用，先看下代码，如下:&lt;/p&gt;</description></item><item><title>C#学习-C# 2.0</title><link>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c%23%E5%AD%A6%E4%B9%A0-c%23-2.0/</link><pubDate>Sun, 05 Dec 2021 20:27:45 +0000</pubDate><guid>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c%23%E5%AD%A6%E4%B9%A0-c%23-2.0/</guid><description>&lt;h2 id="c-20-版本"&gt;C# 2.0 版本&lt;/h2&gt;
&lt;p&gt;在 C# 2.0 版本提供的特性如下:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;泛型&lt;/li&gt;
&lt;li&gt;分部类型（partial）&lt;/li&gt;
&lt;li&gt;匿名方法&lt;/li&gt;
&lt;li&gt;可以为 null 的值类型&lt;/li&gt;
&lt;li&gt;迭代器&lt;/li&gt;
&lt;li&gt;协变和逆变&lt;/li&gt;
&lt;li&gt;getter/setter 单独可访问性&lt;/li&gt;
&lt;li&gt;方法组转换（委托）&lt;/li&gt;
&lt;li&gt;静态类&lt;/li&gt;
&lt;li&gt;委托推断&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="image.png" loading="lazy" src="https://blog-1308267163.cos.ap-shanghai.myqcloud.com/imgs/202211191928011.png"&gt;&lt;/p&gt;
&lt;h2 id="泛型"&gt;泛型&lt;/h2&gt;
&lt;p&gt;最常用的 List&lt;T&gt; 就是泛型的一个应用。&lt;/p&gt;
&lt;p&gt;C# 文档地址：&lt;a href="https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/generics/index"&gt;泛型&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="泛型-api-的设计"&gt;泛型 API 的设计&lt;/h3&gt;
&lt;p&gt;要设计一个泛型 的 API 非常简单，看以下代码中的 GetTypeName 方法。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;UnityEngine&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;QFramework.Master&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReflectionExample&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MonoBehaviour&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;GetTypeName&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Awake&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GetTypeName&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 输出结果:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// String&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;泛型可以把一个类或者一个方法，当做一个模板，而这个模板所需要填充的内容则是定义的各种类型，所以泛型可以最大限度地实现代码的复用。&lt;/p&gt;
&lt;h3 id="c-什么要实现泛型"&gt;C# 什么要实现泛型？&lt;/h3&gt;
&lt;p&gt;C# 实现泛型这个特性，肯定是为了解决开发者遇到的实际问题的，要想知道泛型具体解决了什么问题，那么就要回过头看看没实现泛型之前的 C# 语言有什么样的问题？&lt;/p&gt;
&lt;p&gt;在 C# 实现泛型之前，我们只能使用 ArrayList 来充当不定长的数组。&lt;/p&gt;</description></item><item><title>C#学习-C# 1.0</title><link>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c%23%E5%AD%A6%E4%B9%A0-c%23-1.0/</link><pubDate>Wed, 01 Dec 2021 22:32:41 +0000</pubDate><guid>https://liuyingbo.com/posts/%E8%AF%AD%E6%B3%95/c%23%E5%AD%A6%E4%B9%A0-c%23-1.0/</guid><description>&lt;h2 id="c-10"&gt;C# 1.0&lt;/h2&gt;
&lt;p&gt;我们先罗列一下 C# 1.0 发布时所包含的语法特性，如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;类（class）&lt;/li&gt;
&lt;li&gt;结构（struct）&lt;/li&gt;
&lt;li&gt;接口（interface）&lt;/li&gt;
&lt;li&gt;事件（event）&lt;/li&gt;
&lt;li&gt;属性（property）&lt;/li&gt;
&lt;li&gt;委托（delegates）&lt;/li&gt;
&lt;li&gt;表达式&lt;/li&gt;
&lt;li&gt;语句&lt;/li&gt;
&lt;li&gt;特性（有时候也叫属性）（Attribute）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C# 1.0 的特性只有以上这些。&lt;/p&gt;
&lt;p&gt;基本上它涵盖了 C# 中最常用、最核心、最基础部分的内容。C# 使用进阶，一些非常基础的东西就不记录了。&lt;/p&gt;
&lt;p&gt;&lt;img alt="image.png" loading="lazy" src="https://blog-1308267163.cos.ap-shanghai.myqcloud.com/imgs/202211191926400.png"&gt;&lt;/p&gt;
&lt;h2 id="类"&gt;类&lt;/h2&gt;
&lt;p&gt;单纯从功能上来说，类可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;包含变量（属性）&lt;/li&gt;
&lt;li&gt;包含方法（行为）&lt;/li&gt;
&lt;li&gt;继承&lt;/li&gt;
&lt;li&gt;用来创建对象&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="image.png" loading="lazy" src="https://blog-1308267163.cos.ap-shanghai.myqcloud.com/imgs/202211191926942.png"&gt;&lt;/p&gt;
&lt;h3 id="面向对象与面向过程"&gt;面向对象与面向过程&lt;/h3&gt;
&lt;p&gt;有了类我们比较容易地进行面向对象编程，没有类当然也可以面向对象编程，只不过会不那么容易做到。&lt;/p&gt;
&lt;p&gt;那么什么是面向对象编程呢？&lt;/p&gt;
&lt;p&gt;我的理解只有两个字，建模。&lt;/p&gt;
&lt;p&gt;建模就是对需要实现的功能或者需要解决的问题建立业务模型。&lt;/p&gt;
&lt;p&gt;比如要实现购买商品功能，就需要我们创建商品对象，还要把购买商品的行为归属到另一个对象中，这个对象有可能是顾客对象，也有可能是平台对象。&lt;/p&gt;
&lt;p&gt;这就是非常典型的面向对象建模案例。&lt;/p&gt;
&lt;p&gt;那么如果是面向过程中的购买商品会是什么样的呢？&lt;/p&gt;
&lt;p&gt;我们也许这样考虑，购买商品先创建一个购买商品函数，然后函数可能需要调用数据库，那就再写一个调用数据库的函数交媾购买商品函数调用，依次类推。&lt;/p&gt;
&lt;p&gt;其实要区分面向对象编程与面向过程编程非常容易。&lt;/p&gt;
&lt;p&gt;面向对象编程是以对象为基础进行思考的，而面向过程是以功能（函数）为基础进行思考的。&lt;/p&gt;
&lt;p&gt;这就是两者的差别。&lt;/p&gt;
&lt;h3 id="面向对象与面向过程是对立的吗"&gt;面向对象与面向过程是对立的吗？&lt;/h3&gt;
&lt;p&gt;不是对立的，面向对象更擅设计，而面向过程更擅长实现。&lt;/p&gt;
&lt;p&gt;在使用 C# 的时候，两种编程思维都是会用到的。&lt;/p&gt;
&lt;h3 id="没有类如何面向对象编程"&gt;没有类如何面向对象编程？&lt;/h3&gt;
&lt;p&gt;面向对象编程，当然要有对象了，如果没有类的话，其实也可以实现面向对象编程。&lt;/p&gt;
&lt;p&gt;c 语言虽然不支持类，但是也可以通过宏或者一些模拟的手段支持类和对象的。&lt;/p&gt;
&lt;p&gt;Lua 语言也没有提供类功能，但是通过元表也是能够模拟类和对象的。&lt;/p&gt;
&lt;p&gt;OK，到此，面向对象这个话题可能与我们的专栏话题不太对题，但是一想到类，就不自觉地扯到面向对象这个话题了。&lt;/p&gt;
&lt;p&gt;总是面向对象编程的核心就是两个字：建模。&lt;/p&gt;
&lt;p&gt;&lt;img alt="image.png" loading="lazy" src="https://blog-1308267163.cos.ap-shanghai.myqcloud.com/imgs/202211191927703.png"&gt;&lt;/p&gt;
&lt;h3 id="引用类型和值类型"&gt;引用类型和值类型&lt;/h3&gt;
&lt;p&gt;几乎在每一本编程语言书籍上都会谈到引用类型和值类型这两个概念。&lt;/p&gt;
&lt;p&gt;具体的引用类型和值类型相关的细节，大家在网上找各种文章就可以了。&lt;/p&gt;
&lt;p&gt;引用类型，是用类创建的类型就是引用类型。&lt;/p&gt;
&lt;p&gt;值类型包含基础类型和结构体（struct）创建出来的类型。&lt;/p&gt;
&lt;p&gt;如下：
&lt;img alt="image.png" loading="lazy" src="https://blog-1308267163.cos.ap-shanghai.myqcloud.com/imgs/202211191927309.png"&gt;&lt;/p&gt;
&lt;p&gt;就是这么简单。&lt;/p&gt;
&lt;h3 id="定义"&gt;定义&lt;/h3&gt;
&lt;p&gt;值类型直接存储其值，而引用类型存储对其值的引用&lt;/p&gt;
&lt;p&gt;值类型 和 引用类型 是非常重要且非常基础的话题，所以想深入研究，网上能够找到一大堆文章。&lt;/p&gt;
&lt;h3 id="类是引用类型"&gt;类是引用类型&lt;/h3&gt;
&lt;p&gt;记住这句话就行。&lt;/p&gt;</description></item></channel></rss>