diff --git a/C#进阶/C#进阶.sln b/C#进阶/C#进阶.sln
index a94403f..8605ea8 100644
--- a/C#进阶/C#进阶.sln
+++ b/C#进阶/C#进阶.sln
@@ -69,6 +69,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lesson16_List排序", "Less
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lesson16_List排序练习", "Lesson16_List排序练习\Lesson16_List排序练习.csproj", "{D6D1193A-668E-454A-BFBF-6186A2C76509}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lesson17_协变逆变", "Lesson17_协变逆变\Lesson17_协变逆变.csproj", "{123A2A95-0776-4C76-8570-4D879159D362}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lesson17_协变逆变练习", "Lesson17_协变逆变练习\Lesson17_协变逆变练习.csproj", "{DDF7EBE2-4B8E-4B48-97BC-06EB4E55796A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -207,6 +211,14 @@ Global
{D6D1193A-668E-454A-BFBF-6186A2C76509}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6D1193A-668E-454A-BFBF-6186A2C76509}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6D1193A-668E-454A-BFBF-6186A2C76509}.Release|Any CPU.Build.0 = Release|Any CPU
+ {123A2A95-0776-4C76-8570-4D879159D362}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {123A2A95-0776-4C76-8570-4D879159D362}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {123A2A95-0776-4C76-8570-4D879159D362}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {123A2A95-0776-4C76-8570-4D879159D362}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DDF7EBE2-4B8E-4B48-97BC-06EB4E55796A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DDF7EBE2-4B8E-4B48-97BC-06EB4E55796A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DDF7EBE2-4B8E-4B48-97BC-06EB4E55796A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DDF7EBE2-4B8E-4B48-97BC-06EB4E55796A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/C#进阶/Lesson17_协变逆变/Lesson17_协变逆变.csproj b/C#进阶/Lesson17_协变逆变/Lesson17_协变逆变.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/C#进阶/Lesson17_协变逆变/Lesson17_协变逆变.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/C#进阶/Lesson17_协变逆变/Program.cs b/C#进阶/Lesson17_协变逆变/Program.cs
new file mode 100644
index 0000000..aa18dab
--- /dev/null
+++ b/C#进阶/Lesson17_协变逆变/Program.cs
@@ -0,0 +1,86 @@
+namespace Lesson17_协变逆变
+{
+ #region 知识点一 什么是协变逆变
+ //协变:
+ //和谐的变化,自然的变化
+ //因为 里氏替换原则 父类可以装子类
+ //所以 子类变父类
+ //比如 string 变 object
+ //感受是和谐的
+
+ //逆变:
+ //逆常规的变化,不正常的变化
+ //因为 里氏替换原则 父类可以装子类 但子类不能装父类
+ //所以 父类变子类
+ //比如 object 变 string
+ //感受是不正常的
+
+ //协变和逆变是用来修饰泛型的
+ //协变:out
+ //逆变:in
+ //用于在泛型中 修饰 泛型字母
+ //只有泛型接口和泛型委托能使用
+ #endregion
+
+ #region 知识点二 作用
+ //1.返回值 和 参数
+ //用 out 修饰的泛型 只能作为返回值 不能作为参数
+ delegate T TestOut();
+ //用 in 修饰的泛型 只能作为参数 不能作为返回值
+ delegate void TestIn(T t);
+ //注意:只能在泛型接口和泛型委托中使用
+
+ interface Test
+ {
+ void TestFun(T v);
+ T2 TestFun2();
+ }
+
+
+
+
+ //2.结合里氏替换原则理解
+
+ class Father
+ {
+
+ }
+
+ class Son : Father
+ {
+
+ }
+ #endregion
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ #region 知识点三 (结合里氏替换原则)
+ //协变:子类变父类
+ TestOut os = () =>
+ {
+ return new Son();
+ };
+ TestOut of = os;//不能直接装,TestOut必须通过协变的方式才能装os
+ Father f = of();//实际返回的是Son类型的对象
+
+ //逆变:父类变子类
+ TestIn iF = (value) =>
+ {
+
+ };
+ TestIn iS = iF;//不能直接装,TestIn必须通过逆变的方式才能装iF
+ iS(new Son());//实际传递进去的是Father类型的对象
+ #endregion
+ }
+ }
+}
+//总结
+//协变 out
+//逆变 in
+//用来修饰 泛型替代符的 只能修饰接口和委托中的泛型
+
+//作用两点
+//1.out修饰的泛型类型 只能作为返回值类型 in修饰的泛型类型 只能作为 参数类型
+//2.遵循里氏替换原则的 用out和in修饰的 泛型委托 可以相互装载(有父子关系的泛型)
+// 协变 父类泛型委托装子类泛型委托 逆变 子类泛型委托装父类泛型委托
\ No newline at end of file
diff --git a/C#进阶/Lesson17_协变逆变练习/Lesson17_协变逆变练习.csproj b/C#进阶/Lesson17_协变逆变练习/Lesson17_协变逆变练习.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/C#进阶/Lesson17_协变逆变练习/Lesson17_协变逆变练习.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/C#进阶/Lesson17_协变逆变练习/Program.cs b/C#进阶/Lesson17_协变逆变练习/Program.cs
new file mode 100644
index 0000000..25f6fc8
--- /dev/null
+++ b/C#进阶/Lesson17_协变逆变练习/Program.cs
@@ -0,0 +1,53 @@
+namespace Lesson17_协变逆变练习
+{
+ //协变
+ delegate T TestOut();
+ //逆变
+ delegate void TestIn(T t);
+
+ class Father
+ {
+
+ }
+
+ class Son : Father
+ {
+
+ }
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ #region 练习题一
+ //请简述协变逆变有什么作用
+
+ //协变逆变是用来修饰泛型替代符的 只存在于泛型接口和泛型委托中
+ //1.协变 用 out 修饰 只能作为返回值 不能作为参数
+ //2.逆变 用 in 修饰 只能作为参数 不能作为返回值
+
+ //遵循里氏替换原则 用out和in修饰的泛型委托如果类型是父子关系 那么可以相互装载
+ // 协变:父类泛型委托变量 可以装 子类泛型委托实例
+ // 逆变:子类泛型委托变量 可以装 父类泛型委托实例
+ #endregion
+
+ #region 练习题二
+ //请写出协变逆变的代码示例
+
+ TestOut s = () =>
+ {
+ return new Son();
+ };
+
+ TestOut tf = s;
+ Father f = tf();
+
+ TestIn iF = (value) =>
+ {
+ Console.WriteLine("接受到一个Father类型的参数");
+ };
+ TestIn iS = iF;
+ iS(new Son());
+ #endregion
+ }
+ }
+}