文章目录
- 泛型
- 泛型的使用
- 泛型的约束
- 委托
- 委托的实例化
- 多播委托
- 委托的调用
- 内置委托类型
- 委托练习
- 泛型委托
- Lambda表达式(进阶)
- 上期习题答案
- 本期习题
泛型
泛型(Generic) 是一种规范,它允许我们使用占位符来定义类和方法,编译器会在编译时将这些占位符替换为指定的类型,利用泛型的这一特性我们可以定义通用类(泛型类),方法(泛型方法),接口(泛型接口)。
泛型:广泛的类型,一般用于传递类型
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _01_泛型
{
internal class Program
{
static void Main(string[] args)
{
//泛型:广泛的类型,一般用于传递类型
// <>中间的类型就是传入的泛型
List<int> list = new List<int>();
Dictionary<string,int> keyValuePairs = new Dictionary<string,int>();
//调用的时候,通过<>将类型的实参进行传递,对应位置的泛型形参就是这个类型了
Fnt<int>(1);
Fnt<string>("2");
Fnt<double>(1.1);
Fnt<int>(1, new int[] { 1, 2 });
Fnt<string>("a", new string[] { "a", "b" });
Fnt<int, string>(1, "a");
//泛型可以根据传入的实参,自动推断泛型的类型
Fnt(1);//自动推断泛型为int
Fnt("2");//自动推断泛型为string
}
//泛型的命名规范,一般以T开头的单词命名,尽量能表示这个类型的作用,如果使用一个字母作为泛型,建议使用T
//也就是说,多个字母的时候 使用TXxxx 单独的字母的时候使用T
//泛型在方法中的使用
//在方法名的后面添加<> 里面就相当于是类型的形参列表
public static T Fnt<T>(T a, T[] arrA)
{
return a;
}
public static void Fnt<TTest1,TTset2>(TTest1 a, TTset2 b )
{
}
//接收一个任意类型的数据,转换为对应长度的数组,其中存放对应的数据
public static T[] Fnts<T>(T value,int count)
{
T[] res=new T[count];
for (int i = 0; i < count; i++)
{
res[i] = value;
}
return res;
}
}
//需求: 实现一个方法 这个方法接收一个int类型,返回一个int类型,接收string 返回string...
class Test
{
public int Fn(int value)
{
return value;
}
public string Fn(string value)
{
return value;
}
}
public static T Fnt<T>(T a) //用泛型
{
return a;
}
}
泛型的使用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _02_泛型的使用
{
internal class Program
{
static void Main(string[] args)
{
List<string> list = new List<string>();
People<int, string> p1 = new People<int, string>();
p1.A = 1;
p1.B = "a";
p1.Fn<char>('c', 3, "zifuchuan");
p1.Fn('c', 3, "zifuchuan");
People<int, int> p2 = new People<int, int>();
}
}
}
//--------- 泛型类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _02_泛型的使用
{
//给类添加泛型
internal class People<TTest1,TTest2>
{
//定义一个属性 类型为TTest1类型
public TTest1 A { get; set; }
public TTest2 B { get; set; }
public void Fn<T>(T a,TTest1 b,TTest2 c)
{
}
}
}
//------------泛型接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _02_泛型的使用
{
//泛型接口
internal interface IBook1<T>
{
T A { get; set; }
T B { get; set; }
List<T> C { get; set; }
T[] Fn(T a);
}
class Book : IBook1<int>
{
public int A { get ; set ; }
public int B { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public List<int> C { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public int[] Fn(int a)
{
throw new NotImplementedException();
}
}
class Book2 : IBook1<string>
{
public string A { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public string B { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public List<string> C { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public string[] Fn(string a)
{
throw new NotImplementedException();
}
}
}
泛型的约束
默认泛型是没有约束的,可以传递任意类型的数据
- 声明带有泛型的方法或者类的时候,可以对泛型添加约束,让这个泛型不那么广泛
public void Fn2(T v) where T:struct //T 只能是值类型 - where T : class //T只能是引用类型
- where T : new() 必须是一个类,并且必须拥有无参构造方法
- 必须对泛型进行 where T : new() 约束后 才能进行new操作
- where T : People //T 必须是People类的派生类
- where T : IPeople //T 必须是实现了IPeople接口的类,或者是实现了这个接口的类的子类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _03_泛型的约束
{
internal class Program
{
static void Main(string[] args)
{
//默认泛型是没有约束的,可以传递任意类型的数据
Test test = new Test();
test.Fn1<int>(1);
test.Fn1<string>("a");
test.Fn1<int[]>(new int[] { 1, 2 });
test.Fn1<People>(new People());
//只能传递值类型的数据
test.Fn2<int>(1);
test.Fn2<double>(1.1);
//test.Fn2<string>("a");
//test.Fn2<int[]>(new int[] { 1, 2 });
//test.Fn2<People>(new People());
//只能传递引用类型
//test.Fn3<int>(1);
//test.Fn3<double>(1.1);
test.Fn3<string>("a");
test.Fn3<int[]>(new int[] { 1, 2 });
test.Fn3<People>(new People());
//只能传递拥有无参构造方法类
test.Fn4<People>(new People());
test.Fn5<People>(new People());
test.Fn5<Student>(new Student());
test.Fn5<SamllStudent>(new SamllStudent());
test.Fn6<People>(new People());
test.Fn6<Student>(new Student());
}
class Test
{
public void Fn1<T>(T v) { }
//声明带有泛型的方法或者类的时候,可以对泛型添加约束,让这个泛型不那么广泛
// where T:struct T只能是值类型
public void Fn2<T>(T v) where T : struct { }
//where T : class T只能是引用类型
public void Fn3<T>(T v) where T : class { }
//where T : new() 必须是一个类,并且必须拥有无参构造方法
public void Fn4<T>(T v) where T : new()
{
//必须对泛型进行 where T : new() 约束后 才能进行new操作
T t = new T();
}
//where T : People T 必须是People类的派生类
public void Fn5<T>(T v) where T : People { }
//where T : IPeople T 必须是实现了IPeople接口的类,或者是实现了这个接口的类的子类
public void Fn6<T>(T v) where T : IPeople { }
}
}
interface IPeople
{
}
class People: IPeople
{
}
class Student : People
{
}
class SamllStudent : People
{
}
}
委托
C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。(可以理解为是一种数据类型。)
委托(Delegate)用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。
格式:访问修饰符 delegate 方法的返回值类型 委托的名称(方法的参数…)
委托其实就是一个类型,我们可以使用委托创建一个方法的类型
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//声明一个委托,委托的声明只是声明了一个方法的类型
//格式:访问修饰符 delegate 方法的返回值类型 委托的名称(方法的参数....)
public delegate bool MyDelegate(string v);
namespace _04_委托
{
internal class Program
{
static void Main(string[] args)
{
//C#是强类型的编程语言,强类型编程语言的特性是所有的东西都有特定的类型
//变量,属性 ,字段...在定义的时候都需要显式的指定他们的类型
//方法,之前没有类型,委托其实就是一个类型,我们可以使用委托创建一个方法的类型
Test.TestFn(MyFn);
}
static bool MyFn(string a)
{
Console.WriteLine("这是个函数"+a);
return true;
}
}
class Test
{
//方法接收一个委托类型的参数,就相当于接收一个方法,该方法必须满足这个委托规定的参数和返回值
public static void TestFn(MyDelegate f) {
f("吴凡");
}
}
}
委托的实例化
实例化一个委托的时候必须传递一个方法
MyFns fns1=new MyFns(Fn1);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//1.创建一个委托类型,只能保存没有返回值并且参数为 int和string类型的方法
delegate void MyFns(int v1,string v2);
delegate int NumberOperator(int v1, int v2);
namespace _05_委托的实例化
{
internal class Program
{
static void Main(string[] args)
{
new TestClass();
}
}
class TestClass
{
public TestClass()
{
int a = 1;
//2.实例化一个委托的时候必须传递一个方法
MyFns fns1=new MyFns(Fn1);
Fn1(1, "wuyifan");
//委托类型的变量,可以将它理解为一个特殊的方法,直接将他当做方法调用即可
fns1(1,"luozhxinag");
//练习: 定义一个委托,接收两个int参数,返回int类型参数,并且创建一个委托类型的变量并调用该委托
NumberOperator no = new NumberOperator(Add);
int num1= Add(10,30);
Console.WriteLine(num1);
int num2= no(6,8);
Console.WriteLine(num2);
// NumberOperator no2 = new NumberOperator(Cheng
// 委托创建可以简写
NumberOperator no2 = Cheng;
Console.WriteLine(no2(2,4));
//委托的另外一个调用方法
int v= no2.Invoke(2, 4);
Console.WriteLine(v);
}
void Fn1(int a, string b)
{
Console.WriteLine($"a={a},b={b}");
}
int Add(int a, int b)
{
return a + b;
}
int Cheng(int a, int b)
{
return a * b;
}
}
}
多播委托
- 包含多个方法的委托,称之为多播委托
- 如果这个委托类型的变量,存储了多个方法,当该委托被调用的时候,将会执行所有的方法并传递参数,用+=和-=进行多播的增加与减少
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
delegate void MyDelegate(string name);
namespace _06_多播委托
{
internal class Program
{
static void Main(string[] args)
{
//包含多个方法的委托,称之为多播委托
MyDelegate fns = new MyDelegate(Fn1);
//使用+=运算符,在委托变量上添加一个方法
fns += new MyDelegate(new Test().Fn2);
//如果这个委托类型的变量,存储了多个方法,当该委托被调用的时候,将会执行所有的方法并传递参数
fns("吴亦凡");
//简写
MyDelegate fns2 = Fn1;
fns2 += new Test().Fn2;
fns2("luozhixinag");
MyDelegate fns3 = Fn1;
fns3 += new Test().Fn2;
//还可以使用-=从委托中移除一个方法
fns3 -= Fn1;
fns3("李云迪");
Console.WriteLine("---------------------------");
MyDelegate fns4 = Fn1;
fns4 += new Test().Fn2;
fns4 -= new Test().Fn2;
// 这个委托同样会被调用两次, 因为39行和40行操作的不是同一个方法
//fns4("郑爽");
fns4.Invoke("郑爽");
//一下这些代码 等价于 以上代码
MyDelegate fns5 = Fn1;
Test t1=new Test();
Test t2=new Test();
fns5 += t1.Fn2;
fns5 -= t2.Fn2;
fns5.Invoke("郑爽");
Console.WriteLine("-----------------------------");
//解决方案1:将对象使用变量保存, 执行+=和-=操作
MyDelegate fns6 = Fn1;
Test t=new Test();
fns6 += t.Fn2;
fns6 -= t.Fn2;
fns6.Invoke("郑爽2.0");
//解决方案2:将要加入委托的函数定义为静态函数,用类名调用
MyDelegate fns7 = Fn1;
fns7 += Test.Fn3;
fns7 -= Test.Fn3;
fns7.Invoke("曹云金");
}
public static void Fn1(string v)
{
Console.WriteLine($"这是Fn1中的v:{v}");
}
}
class Test
{
public void Fn2(string v)
{
Console.WriteLine($"这是Fn2中的v:{v}");
}
public static void Fn3(string v)
{
Console.WriteLine($"这是Fn3中的v:{v}");
}
}
}
委托的调用
- 委托被调用的时候,会执行该委托变量中存储的所有的方法
- 当委托中没有存储任何方法的时候,执行会报错:未将对象引用设置到对象的实例 ,解决方法—简写为 ?. 运算符 当前面的值为null的时候 不往后执行
?. 用于从可能为空的值上获取他的属性, 即使该值为null 也不会报错
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _07_委托的调用
{
internal class Program
{
static void Main(string[] args)
{
Test t=new Test();
t.Run();
}
}
class Test
{
public delegate int MyDealegate(int x);
public MyDealegate Fns {get;set; }
public Test()
{
Fns += Fn1;
Fns += Fn2;
}
public int Fn1(int v)
{
Console.WriteLine(v*10);
return v*10;
}
public int Fn2(int v)
{
Console.WriteLine(v * v);
return v * v;
}
People p;
public void Run()
{
//1.委托被调用的时候,会执行该委托变量中存储的所有的方法
//Fns(888);
//2.当委托中没有存储任何方法的时候,执行会报错:未将对象引用设置到对象的实例
// if (Fns != null) Fns(7);
//简写为 ?. 运算符 当前面的值为null的时候 不往后执行
Fns?.Invoke(7);
//?. 用于从可能为空的值上获取他的属性, 即使该值为null 也不会报错
Console.WriteLine(p?.Name==null);
p=new People();
p.Name = "罗志祥";
Console.WriteLine(p?.Name);
}
}
class People
{
public string Name;
}
}
内置委托类型
- Action 用于指定一些不拥有返回值的委托
例:一个接收 int string类型的参数,没有返回值
public static void Fn2(Action<int,string> fn)
- Func 用于指定一些用于返回值的委托
例: 接收int 返回string
public static void Fn5(Func<int,string> fn)
< >中最后一个参数为返回值类型
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//delegate void FnDelegate1();
//delegate void FnDelegate2(int v, string s);
//delegate void FnDelegate3(int v1,int v2);
namespace _08_内置委托类型
{
internal class Program
{
static void Main(string[] args)
{
Test.Fn1(f1);
Test.Fn2(f2);
Test.Fn3(f3);
Test.Fn4(f4);
Test.Fn5(f5);
//这种形式的创建委托比较麻烦,如果该委托只用一次,当做方法的参数的时候,就显得代码比较臃肿,
//c#内置了一些委托, 通过泛型指定他的参数类型
//Action Func
}
static void f1() { }
static void f2(int i,string s) { }
static void f3(int[] i1, bool[] b2) { }
static string f4() { return "123"; }
static string f5(int i) { return "123"; }
}
class Test
{
//一个不接收参数,没有返回值
//Action 用于指定一些不拥有返回值的委托
public static void Fn1(Action fn)
{
}
//一个接收 int string类型的参数,没有返回值
public static void Fn2(Action<int,string> fn)
{
}
//一个接收 int[] bool[] 没有返回值
public static void Fn3(Action<int[], bool[]> fn)
{
}
//一个不接收参数 返回string
//Func 用于指定一些用于返回值的委托
public static void Fn4(Func<string> fn)
{
}
//接收int 返回string
public static void Fn5(Func<int,string>fn)
{
}
//接收int 返回 int
public static void Fn6(Func<double,int> fn)
{
}
}
}
委托练习
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _09_委托练习
{
internal class Program
{
static void Main(string[] args)
{
int[] ints = new int[] { 1, 2, 43, 5, 56, 6, 7 };
//int num1= Array.Find(ints,Fn2);
int num2 = FindFrist(ints, Fn2);
Console.WriteLine(num2);
//自定义Find
}
public static bool Fn2(int value)
{
return value % 2 == 0;
}
public static int FindFrist(int[] ints,Func<int,bool> fn)
{
for (int i = 0; i < ints.Length; i++)
{
if (fn(ints[i])==true)
{
return ints[i];
}
}
return 0;
}
}
}
泛型委托
当定义一个方法,返回值为泛型(例如名为T)时,方法体中可以使用default(T)来返回当前类型的默认值。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
delegate bool CAllBack<T>(T s);
namespace _10_泛型委托
{
internal class Program
{
static void Main(string[] args)
{
string[] strings = { "亦凡1", "吴亦凡2", "罗志祥" };
string s = FindFirst<string>(strings, FindWu);
int[] ints = { 1, 3, 5, 6, 5 };
// int i=FindFirst<int>(ints, FindEven);
int i = FindFirst<int>(ints, FindEven);
Console.WriteLine(i);
}
static bool FindWu(string name)
{
return name.StartsWith("吴");
}
static bool FindEven(int value)
{
return value%2 == 0;
}
//public static string FindFirst(string[] Arrs, CAllBack fn)
//{
// for (int i = 0; i < Arrs.Length; i++)
// {
// if (fn(Arrs[i])==true)
// {
// return Arrs[i];
// }
// }
// return null;
//}
//public static T FindFirst<T>(T[] Arrs, CAllBack<T> fn)
//{
// for (int i = 0; i < Arrs.Length; i++)
// {
// if (fn(Arrs[i]) == true)
// {
// return Arrs[i];
// }
// }
// //返回当前类型的默认值
// return default(T);
//}
//最优写法
public static T FindFirst<T>(T[] Arrs, Func<T,bool> fn)
{
for (int i = 0; i < Arrs.Length; i++)
{
if (fn(Arrs[i]) == true)
{
return Arrs[i];
}
}
//返回当前类型的默认值
return default(T);
}
}
}
Lambda表达式(进阶)
- 格式:Func<参数1的类型,参数2的类型,返回值类型>fnName(参数1,参数2)=>{函数的内容}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _11_Lambda表达式_进阶_
{
internal class Program
{
static void Main(string[] args)
{
int Add(int x,int y)
{
return x + y;
}
//Lambda表达式 用于创建一个函数
Console.WriteLine(Add(1,2));
Func<int, int, int> Add = (a, b) =>
{
return a + b;
};
fn1(1,"吴凡");
//格式:Func<参数1的类型,参数2的类型,返回值类型>fnName(参数1,参数2)=>{函数的内容}
Func<int, int, bool> fnName1 = (int a, int b) =>
{
return a > b;
};
//调用的时候和普通的函数相同
Console.WriteLine(fnName1(19, 10));
//lambda表达式的声明可以简化
//1.函数的实现中,参数的类型可以省略
Func<int, int, bool> fnName2 = (a, b) =>
{
return a > b;
};
//2.如果只有一个参数,可以省略()
Func<int, bool> fnName3 = a =>
{
return a % 2 == 0;
};
//3.如果函数中只有一个表达式,,可以省略{}和return,他会自动返回表达式的运行结果
Func<int, bool> fnName4 = a => a % 2 == 0;
//如下代码和53代码等价
Func<int, int, bool> fnName5 = (a, b) => a > b;
int[] ints = new int[] { 3, 4, 5, 6 };
FindFirst(ints, FindEven);
FindFirst(ints, v => v % 2 == 0);
}
static bool FindEven(int value)
{
return value % 2 == 0;
}
public static T FindFirst<T>(T[] Arrs, Func<T, bool> fn)
{
for (int i = 0; i < Arrs.Length; i++)
{
if (fn(Arrs[i]) == true)
{
return Arrs[i];
}
}
//返回当前类型的默认值
return default(T);
}
}
}
上期习题答案
- 创建一个用于存储某公司员工信息的类Employee,并且可以通过索引来访问员工的姓名和年龄。(提示:使用字典)
Employee employee = new Employee();
employee[22] = "fanfan"; // 员工年龄22,名字 fanfan
employee[22] = "luoluo"; // 员工年龄22,名字 luoluo
employee[23] = "Bob"; 员工年龄23,名字 Bob
employee["aa"] = 25;
employee["Bob"] = 29; //修改Bob的年龄为29
- 创建一个名为DictionaryWrapper的类,它包装了一个Dictionary对象,并提供了一个索引器,允许我们通过键的部分名称来访问字典中的值。(提示,索引器可以接收多个参数)
> DictionaryWrapper dictionaryWrapper = new DictionaryWrapper(); //
> 设置字典中的键值对 dictionaryWrapper["dog"] = "狗"; dictionaryWrapper["cat"] =
> "猫"; dictionaryWrapper["elephant"] = "大象";
> dictionaryWrapper["dolphin"] = "海豚";
>
> // 输出字典中的值 Console.WriteLine("通过完整键访问:"); Console.WriteLine("dog的值是:"
> + dictionaryWrapper["dog"]); // 狗 Console.WriteLine("cat的值是:" + dictionaryWrapper["cat"]); // 猫 Console.WriteLine("elephant的值是:" +
> dictionaryWrapper["elephant"]); // 大象 Console.WriteLine("dolphin的值是:"
> + dictionaryWrapper["dolphin"]); // 海豚
>
> Console.WriteLine("\n通过键的部分名称访问:");
> Console.WriteLine("以\"do\"开头的键的第一个值是:" + dictionaryWrapper["do", 0]);
> // 狗 Console.WriteLine("以\"do\"开头的键的第二个值是:" + dictionaryWrapper["do",
> 1]); // 海豚
参考答案(1,2答案在同一项目下)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 上周作业
{
internal class Program
{
static void Main(string[] args)
{
Employee employee = new Employee();
//设置员工的姓名和年龄
employee[22] = "fanfan"; // 员工年龄22,名字 fanfan
employee[22] = "luoluo"; // 员工年龄22,名字 luoluo
employee[23] = "Bob"; 员工年龄23,名字 Bob
employee["aa"] = 25;
employee["Bob"] = 29; //修改Bob的年龄为29
Console.WriteLine(employee[22]);
Console.WriteLine(employee["Bob"]);
//------------------------------------------------------------
DictionaryWrapper dictionaryWrapper = new DictionaryWrapper();
// 设置字典中的键值对
dictionaryWrapper["dog"] = "狗";
dictionaryWrapper["cat"] = "猫";
dictionaryWrapper["elephant"] = "大象";
dictionaryWrapper["dolphin"] = "海豚";
// 输出字典中的值
Console.WriteLine("通过完整键访问:");
Console.WriteLine("dog的值是:" + dictionaryWrapper["dog"]);// 狗
Console.WriteLine("dog的值是:{0}", dictionaryWrapper["dog"]); // 狗
Console.WriteLine(@"dog的值是:{dictionaryWrapper[""dog""]}");
Console.WriteLine("cat的值是:" + dictionaryWrapper["cat"]); // 猫
Console.WriteLine("elephant的值是:" + dictionaryWrapper["elephant"]); // 大象
Console.WriteLine("dolphin的值是:" + dictionaryWrapper["dolphin"]); // 海豚
Console.WriteLine("\n通过键的部分名称访问:");
Console.WriteLine("以\"do\"开头的键的第一个值是:" + dictionaryWrapper["do", 0]); // 狗
Console.WriteLine("以\"do\"开头的键的第二个值是:" + dictionaryWrapper["do", 1]); // 海豚
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 上周作业
{
/// <summary>
/// 字典的包装类
/// </summary>
internal class DictionaryWrapper
{
//存储键值对
Dictionary<string, string> map = new Dictionary<string, string>();
public string this[string englishName]{
get => map[englishName];
set => map[englishName] = value;
}
/// <summary>
/// 根据名字的开头进行查询
/// </summary>
/// <param name="starName">key以什么开头</param>
/// <param name="num">要找第几个,从0开始</param>
/// <returns></returns>
public string this[string starName,int num]
{
get
{
//1.定义一个数字,记录当前找到了第几个
int nowCount = 0;
//2.遍历字典,查询对应的键值对中key 以starName开头的
foreach (var item in map)
{
//判断key是否以starName开头
if (item.Key.StartsWith(starName))
{
//相同 判断当前找到的是否为低num个
if (nowCount==num)
{
//如果个数匹配,则返回当前查到的数据
return item.Value;
}
else
{
//个数如果不匹配 则个数累加
nowCount++;
}
}
}
//如果没有找到返回null
return null;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace 上周作业
{
/// <summary>
/// 员工信息类
/// </summary>
internal class Employee
{
//字典: 存储所有员工的信息
Dictionary<int, string> peoples =new Dictionary<int,string>();
public string this[int index]
{
get {
//根据key获取value
//如果这个key存在,则返回对应key的值,否则返回null
return peoples.ContainsKey(index) ? peoples[index]:null;
}
set {
//字典也可以进行[key]=value的方式进行操作
//如果字段中对应的key存在,则修改,不存在则添加
peoples[index] = value;
//if (peoples.ContainsKey(index))//判断字典中是否存在指定的键
//{
// peoples[index] = value;//如果存在则进行修改
//}
//else
//{
// peoples.Add(index, value);//如果不存在则进行添加
//}
}
}
public int this[string name]
{
get {
//查询字典中满足条件的键值对,如果没有则返回默认值
return peoples.FirstOrDefault(item => item.Value == name).Key;
}
set {
//先判断是否有个人 叫name 如果有 则将他先删除
if (peoples.ContainsValue(name))
{
//foreach (var item in peoples)
//{
// Console.WriteLine($"当前的键{item.Key}当前的的值{item.Value}");
// //判断当前的将只对是否为我们需要找的键值对,
// if (item.Value == name)
// {
// //先移出之前的键值对
// peoples.Remove(item.Key);
// }
//}
// 查询对应的值相同的那个键值对的键
//移除之前Ian那个键值对
int key = this[name];
peoples.Remove(key);
}
//添加新的键值对
Console.WriteLine("value"+value);
Console.WriteLine("name"+name);
peoples.Add(value, name);
}
}
}
}
本期习题
-
模拟List
MyList myList1 = new MyList();
myList1.Add(1);
myList1.Add(20);
-
自定义 ForEach FindIndex Find…
觉得本篇文章写的还不错可以点赞,收藏,关注。主页有21天速通C#教程欢迎订阅!!!