C#_泛型_委托

news2024/10/11 10:18:35

文章目录

    • 泛型
    • 泛型的使用
    • 泛型的约束
    • 委托
    • 委托的实例化
    • 多播委托
    • 委托的调用
    • 内置委托类型
    • 委托练习
    • 泛型委托
    • 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();
        }
    }

}


泛型的约束

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

  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接口的类,或者是实现了这个接口的类的子类
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;
        }
    }

}

多播委托

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

?. 用于从可能为空的值上获取他的属性, 即使该值为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;
    }

}

内置委托类型

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

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

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

    }
}

上期习题答案

  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
  1. 创建一个名为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#教程欢迎订阅!!!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1553955.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多模态检索增强生成的简单介绍

原文地址&#xff1a;An Easy Introduction to Multimodal Retrieval Augmented Generation 2024 年 3 月 20 日 如果检索增强生成(RAG) 应用程序可以处理多种数据类型&#xff08;表格、图形、图表和图表&#xff09;而不仅仅是文本&#xff0c;那么它的实用性就会呈指数级…

【能省则省】搭建网站仅50/年 云服务器选择建议 程序员职场刚需云产品 附最新价格对比表

《最新对比表》已更新在文章头部—腾讯云文档&#xff0c;文章具有时效性&#xff0c;请以腾讯文档为准&#xff01; 【腾讯文档实时更新】云服务器1分钟教会你如何选择教程 2024-开年采购活动 云服务器专区 京东云 阿里云 腾讯云 配置最新价格表 与 官方活动地址 ​ 当前活动…

Docker进阶:Docker Swarm(集群搭建) —实现容器编排的利器

Docker进阶&#xff1a;Docker Swarm&#xff08;集群搭建&#xff09; —实现容器编排的利器 1、什么是Docker Swarm&#xff1f;2、Docker Swarm 与 Docker Compose的区别3、创建一个Swarm集群&#xff08;1-Manager&#xff0c;2-Worker&#xff09;1、资源准备2、初始化Swa…

机器人姿态估计-IMU、互补滤波算法应用

机器人姿态估计-IMU、互补滤波算法应用 附赠自动驾驶学习资料和量产经验&#xff1a;链接 机器人的姿态测量对于许多应用至关重要&#xff0c;如导航、运动控制等。在这篇文章中&#xff0c;我们将介绍如何利用MPU6050传感器以及互补滤波和卡尔曼滤波算法来实现自平衡车的姿态…

vue 实现自定义分页打印 window.print

首先这里是我自定义了打印界面才实现的效果&#xff0c;如果不用自定义界面实现&#xff0c;应该是一样的吧。具体可能需要自己去试试看 我的需求是界面有两个表格&#xff0c;点击全部打印&#xff0c;我需要把第一表格在打印是第1页&#xff0c;第二个表格是第二页 如图&…

二十二、软考-系统架构设计师笔记-真题解析-2018年真题

软考-系统架构设计师-2018年上午选择题真题 考试时间 8:30 ~ 11:00 150分钟 1.在磁盘调度管理中&#xff0c;应先进行移臂调度&#xff0c;再进行旋转调度。假设磁盘移动臂位于21号柱面上&#xff0c;进程的请求序列如下表所示。如果采用最短移臂调度算法&#xff0c;那么系统…

ensp中pc机访问不同网络的服务器

拓扑图如下&#xff0c;资源已上传 说明&#xff1a;pc通过2个路由访问server服务器 三条线路分别是192.168.1.0网段&#xff0c;192.168.2.0网段和192.168.3.0网段&#xff0c;在未配置的情况下&#xff0c;pc设备是访问不到server的 具体操作流程 第一&#xff1b;pc设备…

C# 操作 Word 全域查找且替换(含图片对象)

目录 关于全域查找且替换 Word应用样本 SqlServer数据表部分设计样本 范例运行环境 配置Office DCOM 设计实现 组件库引入 实现原理 查找且替换的核心代码 窗格内容 页眉内容 页脚内容 形状内容 小结 关于全域查找且替换 C#全域操作 Word 查找且替换主要包括如下…

CSGO赛事管理系统的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目持续更新中..... 2024年计算机毕业论文&#xff08;设计&#xff09;学生选题参考合集推荐收藏&#xff08;包含Springboot、jsp、ssmvue等技术项目合集&#xff09; 目录 1. 系…

QT数据类型和容器用法

Qt库提供了基于通用模板的容器类, 这些类可用于存储指定类型的数据项&#xff0c;Qt中这些容器类的设计比STL容器更轻&#xff0c;更安全且更易于使用。容器类也都是隐式共的&#xff0c;它们是可重入的&#xff0c;并且已针对速度/低内存消耗和最小的内联代码扩展进行了优化&a…

RabbitMQ基础笔记

视频链接&#xff1a;【黑马程序员RabbitMQ入门到实战教程】 文章目录 1.初识MQ1.1.同步调用1.2.异步调用1.3.技术选型 2.RabbitMQ2.1.安装2.1.1 Docker2.1.1 Linux2.1.1 Windows 2.2.收发消息2.2.1.交换机2.2.2.队列2.2.3.绑定关系2.2.4.发送消息 2.3.数据隔离2.3.1.用户管理2…

Elasticsearch:语义搜索即服务处于卓越搜索的中心

作者&#xff1a;来自 Elastic Sherry Ger, Stephen Brown 对于许多企业来说&#xff0c;搜索卓越中心&#xff08;center of excellence - COE&#xff09;向其用户提供搜索服务&#xff0c;从不同的数据源中整理知识&#xff0c;并将搜索功能集成到其内部和外部应用程序中。…

神策数据参与制定首份 SDK 网络安全国家标准

国家市场监督管理总局、国家标准化管理委员会发布中华人民共和国国家标准公告&#xff08;2023 年第 13 号&#xff09;&#xff0c;全国信息安全标准化技术委员会归口的 3 项国家标准正式发布。其中&#xff0c;首份 SDK 国家标准《信息安全技术 移动互联网应用程序&#xff0…

如何配置本地ssh连接远程Linux服务器

1.条件 本地操作系统Ubuntu远程服务器&#xff08;Linux都可以&#xff09; 本地如果是Window,其实也一样&#xff0c;但是需要先下载ssh和putty工具&#xff0c;然后操作步骤是一样的 2.生成ssh公私钥对 # 在本地重新生成SSH公私钥对非常简单&#xff0c;在你的命令行终端&a…

词令关键词口令直达工具:打开「词令」输入关键词直达口令怎么使用?

词令是一款关键词口令直达工具&#xff1b;使用词令关键词口令直达工具&#xff0c;输入指定的词令关键词直达口令&#xff0c;搜索直达该词令关联的网站、页面、程序、应用、服务或功能等等&#xff0c;实现一键直达目标&#xff0c;避免繁琐的查找点击行为&#xff0c;提高用…

报错 /core/library/think/cache/driver/File.php 第 126 行左右(已解决)

报错 /core/library/think/cache/driver/File.php 第 126 行左右 解决方法&#xff1a; 网站后台版本低于v1.5.2出现的缓存问题&#xff0c;如果无法登录后台了&#xff0c;就通过FTP&#xff0c;把 /data/runtime 里的都删掉&#xff0c;然后进后台升级到最新版 一、进入宝…

初步了解JavaSE

目录 前言&#xff1a; 一、Java SE主要包含模块&#xff1a; 二、JavaSE的环境搭建 三、JavaSE简单入门 1&#xff09;文件名称不对&#xff0c;如果有一个叫 helloworld.java&#xff0c;但是class命名为HelloWord. 2&#xff09;如果希望我们文件名称和类名不一致&…

光耦合器电路基本概述

在当今快速发展的技术环境中&#xff0c;光耦合器电路在确保电信号跨隔离电路的无缝传输方面发挥着关键作用。这些半导体器件通常被称为光电隔离器&#xff0c;具有许多优点&#xff0c;包括电路隔离、信号传输和精确的电路控制。然而&#xff0c;如果不全面了解市场上各种光耦…

【漏洞复现】通天星CMSV6 admin 弱口令漏洞(CVE-2024-29666)

0x01 产品简介 CMSV6平台是基于车辆位置信息服务和实时视频传输服务的创新技术和开放运营理念。为GPS运营商车辆硬件设备制造商、车队管理企业等车辆运营相关企业提供核心基础数据服务。 0x02 漏洞概述 CMSV6 7.31.0.2、7.32.0.3版本中存在弱密码漏洞&#xff0c;未授权的攻…

俄罗斯深陷芯片自主困境,良率仅5成 |百能云芯

俄罗斯的芯片产业一直以来都面临着诸多挑战&#xff0c;尤其是在当前的国际形势下&#xff0c;这些挑战更加凸显。随着俄乌冲突的爆发&#xff0c;西方国家对俄罗斯实施了一系列经济制裁&#xff0c;导致俄罗斯科技产业受到了严重影响。据了解&#xff0c;俄国最大的本土芯片厂…