C#_泛型_委托

文章目录

泛型

泛型(Generic) 是一种规范,它允许我们使用占位符来定义类和方法,编译器会在编译时将这些占位符替换为指定的类型,利用泛型的这一特性我们可以定义通用类(泛型类),方法(泛型方法),接口(泛型接口)。

泛型:广泛的类型,一般用于传递类型

C# 复制代码
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;
        }
   
}

泛型的使用

C# 复制代码
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();
        }
    }

}

泛型的约束

默认泛型是没有约束的,可以传递任意类型的数据

  1. 声明带有泛型的方法或者类的时候,可以对泛型添加约束,让这个泛型不那么广泛
    public void Fn2(T v) where T:struct T 只能是值类型
  2. where T : class T只能是引用类型
  3. where T : new() 必须是一个类,并且必须拥有无参构造方法
  4. 必须对泛型进行 where T : new() 约束后 才能进行new操作
  5. where T : People T 必须是People类的派生类
  6. where T : IPeople T 必须是实现了IPeople接口的类,或者是实现了这个接口的类的子类
C# 复制代码
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 方法的返回值类型 委托的名称(方法的参数...)

委托其实就是一个类型,我们可以使用委托创建一个方法的类型

C# 复制代码
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);

C# 复制代码
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;
        }
    }

}

多播委托

  1. 包含多个方法的委托,称之为多播委托
  2. 如果这个委托类型的变量,存储了多个方法,当该委托被调用的时候,将会执行所有的方法并传递参数,用+=和-=进行多播的增加与减少
C# 复制代码
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}");
        }
    }
}

委托的调用

1.委托被调用的时候,会执行该委托变量中存储的所有的方法

2.当委托中没有存储任何方法的时候,执行会报错:未将对象引用设置到对象的实例 ,解决方法---简写为 ?. 运算符 当前面的值为null的时候 不往后执行

C# 复制代码
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;
    }

}

内置委托类型

  1. Action 用于指定一些不拥有返回值的委托
    例:一个接收 int string类型的参数,没有返回值

public static void Fn2(Action<int,string> fn)

  1. Func 用于指定一些用于返回值的委托
    例: 接收int 返回string

public static void Fn5(Func<int,string>fn)

< >中最后一个参数为返回值类型

C# 复制代码
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)
        {

        }
    }
}

委托练习

C# 复制代码
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;
        }

    }

}

泛型委托

C# 复制代码
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)=>{函数的内容}
C# 复制代码
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));

            Action<int, string> fn1 = (int argOne, string argTwo) =>
            {
                Console.WriteLine(argOne + argTwo);
            };

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

    }
}

上期习题答案

  1. 创建一个用于存储某公司员工信息的类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
  2. 创建一个名为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);
            }
        }
       
    }
}

本期习题

  1. 模拟List

    MyList myList1 = new MyList();

    ​ myList1.Add(1);

    ​ myList1.Add(20);

  2. 自定义 ForEach FindIndex Find...

觉得本篇文章写的还不错可以点赞,收藏,关注。主页有21天速通C#教程欢迎订阅!!!

相关推荐
聂 可 以2 小时前
推荐几个可以免费下载视频的软件(Neat Download Manager、蜗牛下载助手、bilidown)
windows·开源软件
西瓜本瓜@2 小时前
在Android中如何使用Protobuf上传协议
android·java·开发语言·git·学习·android-studio
言之。2 小时前
别学了,打会王者吧
java·python·mysql·容器·spark·php·html5
机智的人猿泰山2 小时前
java kafka
java·开发语言·kafka
胡攀峰3 小时前
第12章 微调生成模型
人工智能·大模型·llm·sft·强化学习·rlhf·指令微调
yuanlaile3 小时前
AI大模型自然语言处理能力案例演示
人工智能·ai·自然语言处理
Algorithm15763 小时前
谈谈接口和抽象类有什么区别?
java·开发语言
细心的莽夫3 小时前
SpringCloud 微服务复习笔记
java·spring boot·笔记·后端·spring·spring cloud·微服务
264玫瑰资源库5 小时前
问道数码兽 怀旧剧情回合手游源码搭建教程(反查重优化版)
java·开发语言·前端·游戏
pwzs5 小时前
Java 中 String 转 Integer 的方法与底层原理详解
java·后端·基础