From e1dcb664e98e7ae67db04874fa5a63a9ccddc0ba Mon Sep 17 00:00:00 2001 From: feilong Date: Mon, 14 Mar 2022 22:11:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0C#4=E3=80=820?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Contravariance.json" | 7 ++ .../Contravariance.md" | 68 ++++++++++++++++ .../Covariance.json" | 7 ++ .../Covariance.md" | 78 +++++++++++++++++++ .../NamedParam.json" | 7 ++ .../NamedParam.md" | 41 ++++++++++ .../OptionParam.json" | 7 ++ .../OptionParam.md" | 41 ++++++++++ .../config.json" | 11 ++- .../sample/Program.cs" | 67 ++++++++++++++++ .../sample/sample.csproj" | 10 +++ data/tree.json | 4 +- 12 files changed, 343 insertions(+), 5 deletions(-) create mode 100644 "data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Contravariance.json" create mode 100644 "data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Contravariance.md" create mode 100644 "data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Covariance.json" create mode 100644 "data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Covariance.md" create mode 100644 "data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/NamedParam.json" create mode 100644 "data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/NamedParam.md" create mode 100644 "data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/OptionParam.json" create mode 100644 "data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/OptionParam.md" create mode 100644 "data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/sample/Program.cs" create mode 100644 "data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/sample/sample.csproj" diff --git "a/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Contravariance.json" "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Contravariance.json" new file mode 100644 index 0000000..f7f2740 --- /dev/null +++ "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Contravariance.json" @@ -0,0 +1,7 @@ +{ + "type": "code_options", + "author": "huanhuilong", + "source": "Contravariance.md", + "notebook_enable": false, + "exercise_id": "12348524087540ceb975cd9f2d00108f" +} \ No newline at end of file diff --git "a/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Contravariance.md" "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Contravariance.md" new file mode 100644 index 0000000..ab9aa6d --- /dev/null +++ "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Contravariance.md" @@ -0,0 +1,68 @@ +# 逆变(Contravariance) + +假设有一个父类和一个子类: + +```csharp +// 父类和子类 +class Article{ + public string ToString(){ + return "article"; + } +} + +class CodeArticle: Article{ + public string ToString(){ + return "article with code"; + } +} +``` + +那么,通常针对父类的方法是可以传入子类实例的,4.0增加了`逆变(Contravariance)`,也就是父类的泛型实现可以转成子类的泛型接口。 + + +现在有如下代码: + +```csharp +// 逆变 +public interface ISend { + void Send(T t); +} + +public class ArticleSender : ISend{ + public void Send(T t){ + Console.WriteLine("Send:{0}", t.ToString()); + } +} +``` + +以下代码正确的是? + +## 答案 + +```csharp +ISend sender = new ArticleSender
(); +sender.Send(new CodeArticle()); +``` + +## 选项 + +### A + +```csharp +ISend
sender = new ArticleSender(); +sender.Send(new Article()); +``` + +### B + +```csharp +ISend
sender = new ArticleSender(); +sender.Send(new CodeArticle()); +``` + +### C + +```csharp +ISend sender = new ArticleSender
(); +sender.Send(new Article()); +``` \ No newline at end of file diff --git "a/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Covariance.json" "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Covariance.json" new file mode 100644 index 0000000..354a5a3 --- /dev/null +++ "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Covariance.json" @@ -0,0 +1,7 @@ +{ + "type": "code_options", + "author": "huanhuilong", + "source": "Covariance.md", + "notebook_enable": false, + "exercise_id": "0b9afd8bc5ac4139af83b90f7211d41a" +} \ No newline at end of file diff --git "a/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Covariance.md" "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Covariance.md" new file mode 100644 index 0000000..6c765bd --- /dev/null +++ "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/Covariance.md" @@ -0,0 +1,78 @@ +# 协变(Covariance) + +假设有一个父类和一个子类: + +```csharp +// 父类和子类 +class Article{ + public string ToString(){ + return "article"; + } +} + +class CodeArticle: Article{ + public string ToString(){ + return "article with code"; + } +} +``` + +那么,通常可以把子类当作父类来使用,但是如果包了一层泛型在4.0之前是不可以的: + +```csharp +IEnumerable objs = new List { "Keep it simple, stupid" }; +``` + +4.0增加了`协变(Covariance)`特性后则可以支持上述代码,也就是子类的泛型可以转成父类的接口。 + + +现在有如下代码: + +```csharp +// 协变 +public interface ISearch { + T Search(); +} + +public class CodeArticleSearch: ISearch where T:new(){ + public T Search(){ + return new T(); + } +} +``` + +以下代码正确的是? + +## 答案 + +```csharp +ISearch
search = new CodeArticleSearch(); +Article article = search.Search(); +Console.WriteLine(article); +``` + +## 选项 + +### A + +```csharp +ISearch search = new CodeArticleSearch
(); +Article article = search.Search(); +Console.WriteLine(article); +``` + +### B + +```csharp +ISearch
search = new CodeArticleSearch(); +CodeArticle article = search.Search(); +Console.WriteLine(article); +``` + +### C + +```csharp +ISearch search = new CodeArticleSearch<>(Article); +CodeArticle article = search.Search(); +Console.WriteLine(article); +``` \ No newline at end of file diff --git "a/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/NamedParam.json" "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/NamedParam.json" new file mode 100644 index 0000000..5580f16 --- /dev/null +++ "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/NamedParam.json" @@ -0,0 +1,7 @@ +{ + "type": "code_options", + "author": "huanhuilong", + "source": "NamedParam.md", + "notebook_enable": false, + "exercise_id": "eb2c4ef49ddc42feb74258f81f3c3504" +} \ No newline at end of file diff --git "a/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/NamedParam.md" "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/NamedParam.md" new file mode 100644 index 0000000..5a82bab --- /dev/null +++ "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/NamedParam.md" @@ -0,0 +1,41 @@ +# 命名参数 + +4.0引入了命名参数,命名参数让我们可以在调用方法时指定参数名字来给参数赋,还可以调整参数顺序 + +```csharp +static class Test{ + public static List Find(string key, int number, bool sort){ + Console.WriteLine("key:{0}, number:{1}, sort:{2}", key, number, sort); + return new List(){}; + } +} +``` + +以下对函数调用错误的是? + + +## 答案 + +```csharp +Test.Find(key:"hello", number:5); +``` + +## 选项 + +### A + +```csharp +Test.Find(key:"hello", number:5, sort:false); +``` + +### B + +```csharp +Test.Find(key:"hello", sort:false, number:5); +``` + +### C + +```csharp +Test.Find(sort:false, number:5, key:"hello"); +``` \ No newline at end of file diff --git "a/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/OptionParam.json" "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/OptionParam.json" new file mode 100644 index 0000000..48f918c --- /dev/null +++ "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/OptionParam.json" @@ -0,0 +1,7 @@ +{ + "type": "code_options", + "author": "huanhuilong", + "source": "OptionParam.md", + "notebook_enable": false, + "exercise_id": "0cccd130210a4af6aea30df02619a70d" +} \ No newline at end of file diff --git "a/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/OptionParam.md" "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/OptionParam.md" new file mode 100644 index 0000000..489c21b --- /dev/null +++ "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/OptionParam.md" @@ -0,0 +1,41 @@ +# 可选参数 + +4.0引入了可选参数,如下的函数,示例代码如下 + +```csharp +static class Test{ + public static List Find(string key, int number=5, bool sort=false){ + Console.WriteLine("key:{0}, number:{1}, sort:{2}", key, number, sort); + return new List(){}; + } +} +``` + +以下对函数调用错误的是? + + +## 答案 + +```csharp +Test.Find("hello", true, 10); +``` + +## 选项 + +### A + +```csharp +Test.Find("hello"); +``` + +### B + +```csharp +Test.Find("hello", 10); +``` + +### C + +```csharp +Test.Find("hello", 10, true); +``` \ No newline at end of file diff --git "a/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/config.json" "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/config.json" index 77073bb..3d1b86f 100644 --- "a/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/config.json" +++ "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/config.json" @@ -1,13 +1,18 @@ { "node_id": "csharp-d4650354f5f5498e9969fd98bbb40323", "keywords": [ - "互操作特性", "协变和逆变", - "命名参数和可选参数", + "命名参数", + "可选参数", "动态查找" ], "children": [], - "export": [], + "export": [ + "OptionParam.json", + "NamedParam.json", + "Covariance.json", + "Contravariance.json" + ], "keywords_must": [], "keywords_forbid": [] } \ No newline at end of file diff --git "a/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/sample/Program.cs" "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/sample/Program.cs" new file mode 100644 index 0000000..531534e --- /dev/null +++ "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/sample/Program.cs" @@ -0,0 +1,67 @@ +// See https://aka.ms/new-console-template for more information +Console.WriteLine("Hello, World!"); + +// // // 协变代码 +// ISearch
search = new CodeArticleSearch(); +// Article article = search.Search(); +// Console.WriteLine(article); + +// // 逆变代码 +// ISend sender = new ArticleSender
(); +// sender.Send(new CodeArticle()); + + +// Test.Find("hello"); +// Test.Find("hello", 10); +// Test.Find("hello", 10, true); +// Test.Find("hello", true, 10); + + +// Test.Find(key:"hello", number:5); +Test.Find(key:"hello", sort:false, number:5); +Test.Find(sort:false, number:5, key:"hello"); + + +static class Test{ + public static List Find(string key, int number, bool sort){ + Console.WriteLine("key:{0}, number:{1}, sort:{2}", key, number, sort); + return new List(){}; + } +} + + +// 父类和子类 +class Article{ + public string ToString(){ + return "article"; + } +} + +class CodeArticle: Article{ + public string ToString(){ + return "article with code"; + } +} + + +// 协变 +public interface ISearch { + T Search(); +} + +public class CodeArticleSearch: ISearch where T:new(){ + public T Search(){ + return new T(); + } +} + +// 逆变 +public interface ISend { + void Send(T t); +} + +public class ArticleSender : ISend{ + public void Send(T t){ + Console.WriteLine("Send:{0}", t.ToString()); + } +} \ No newline at end of file diff --git "a/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/sample/sample.csproj" "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/sample/sample.csproj" new file mode 100644 index 0000000..40c60dd --- /dev/null +++ "b/data/1..NET\345\210\235\351\230\266/3.C#\347\211\271\346\200\247/2.C#4.0\347\211\271\346\200\247/sample/sample.csproj" @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/data/tree.json b/data/tree.json index 8086254..48ba95e 100644 --- a/data/tree.json +++ b/data/tree.json @@ -210,9 +210,9 @@ "C#4.0特性": { "node_id": "csharp-d4650354f5f5498e9969fd98bbb40323", "keywords": [ - "互操作特性", "协变和逆变", - "命名参数和可选参数", + "命名参数", + "可选参数", "动态查找" ], "children": [], -- GitLab