天天看點

【C#】【Generic】泛型複習筆記

什麼是泛型,泛型有什麼作用?

  • 泛化的類型 , 與具體的相對 。
  • 将具體的變為一般的 ,根據需求進行特化。
  • 避免了類的膨脹、 成員膨脹的問題。
using System;


namespace HelloGeneric
{
    class Program
    {
        static void Main(string[] args)
        {

            //類型膨脹 
            Apple apple = new Apple() { Color = "Red" };
            AppleBox box = new AppleBox() { Cargo = apple };
            Console.WriteLine(box.Cargo.Color);

            Book book = new Book(){Name = "New book"};
            BookBox bookBox = new BookBox() { Cargo = book };
            Console.WriteLine(bookBox.Cargo.Name);

            Box<Apple> box1 = new Box<Apple>() { Cargo = apple };
            Box<Book> box2 = new Box<Book>() { Cargo = book };

            Console.WriteLine(box1.Cargo.Color);
            Console.WriteLine(box2.Cargo.Name);


        }
    }

    class Book
    {
        public string Name { get; set; }
    }

    class Apple
    {
        public string Color { get; set; }
    }

    class AppleBox
    {
        public Apple Cargo { get; set; }
    }

    class BookBox
    {
        public Book Cargo { get; set; }
    }

    //類型參數 辨別符 代表一個泛化的類型
    class Box<TCargo>
    {
        public TCargo Cargo { get; set; }
    }
}

           

泛型接口

  • 泛型類
  • 實作特化的泛型接口類
using System;


namespace HelloGeneric2
{
    class Program
    {
        static void Main(string[] args)
        {
            Student<int> stu = new Student<int>();
            stu.ID = 101;
            stu.Name = "Sai";
        }
    }

    interface IUnique<TId>
    {
        TId ID{get;set;}
    }
	
	//泛型類
    class Student<TId> : IUnique<TId>
    {
        public TId ID { get; set; }
        public string Name { get; set; }
    }
	
	//實作特化的泛型接口
    class Student : IUnique<ulong>
    {
        public ulong ID { get; set; }
        public string Name { get; set; }
    }
}

           

常用的泛型接口、泛型類

  • List 動态數組
  • Dictionary 字典
//List 動态數組
            IList<int> list = new List<int>();
            for (int i = 0; i < 100; i++)
            {
                list.Add(i);
            }

            foreach (var item in list)
            {
                Console.WriteLine(item);
            }

            //Dictionary 字典
            IDictionary<int, string> dict = new Dictionary<int, string>();
            dict[1] = "Sai";
            dict[2] = "Michael";
            Console.WriteLine($"Student #1 is {dict[1]} ,Student #2 is {dict[2]} ");
           

泛型方法

在調用的時候, 類型參數可以自動推斷。不需要顯式的寫特化類型。

using System;
using System.Collections.Generic;

namespace HelloGeneric3
{
    class Program
    {
        static void Main(string[] args)
        {
        	//自動推斷
            var arr = Add(1.1, 2.2);      
            foreach (var item in arr)
            {
                Console.WriteLine(item);
            }
        }

        static int[] Add(int a, int b)
        {
            int[] zip = new int[2];
            zip[0] = a;
            zip[1] = b;
            return zip;
        }

        static T[] Add<T>(T a, T b)
        {
            T[] zip = new T[2];
            zip[0] = a;
            zip[1] = b;
            return zip;
        }
    }
}

           

泛型方法和重載

順序 : 有重載優先調用

using System;
using System.Collections.Generic;

namespace HelloGeneric3
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("====== 泛型方法 ======");
            //var arr = Add(1.1, 2.2);  優先比對對應的非泛型方法
            var arr = Add<double>(1.1, 2.2); //泛型方法
          
            foreach (var item in arr)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine();
        }

        static int[] Add(int a, int b)
        {
            int[] zip = new int[2];
            zip[0] = a;
            zip[1] = b;
            return zip;
        }

        static double[] Add(double a , double b)
        {
            double[] zip = new double[1];
            zip[0] = a + b;
            return zip;
        }

        static T[] Add<T>(T a, T b)
        {
            T[] zip = new T[2];
            zip[0] = a;
            zip[1] = b;
            return zip;
        }
    }
}

           

泛型委托

Action

類型參數格式 : < T > <T1,T2> <T1,T2,T3> …

類型參數表示 : 此委托封裝的方法的參數類型。可以多個參數。

Action委托隻能引用沒有傳回值的方法。

using System;

namespace HelloGeneric4
{
    class Program
    {
        static void Main(string[] args)
        {
            Action<string> a1 = Say;
            a1.Invoke("Sai");
            //a1("Sai");
            Action<int> a2 = Mul;
            a2(1);
        }

        static void Say(string str)
        {
            Console.WriteLine($"Hello {str}!");
        }

        static void Mul(int x)
        {
            Console.WriteLine(x * 100);
        }
    }
}

           

Func

類型參數格式 : <T,TResult> <T1,T2,TResult> <T1,T2,T3,TResult> …

類型參數表示 : 此委托封裝的方法的 參數的類型 和 傳回值的類型。 可以多個參數。

using System;

namespace HelloGeneric4
{
    class Program
    {
        static void Main(string[] args)
        {
            // 會根據委托的類型參數 自動比對對應方法
            Func<double, double, double> func1 = Add;
            var result = func1(100, 200);
            Console.WriteLine(result);
        }

        static int Add(int a, int b)
        {
            return a + b;
        }

        static double Add(double a,double b)
        {
            return a + b;
        }
    }
}

           

泛型與 lambda 表達式

using System;

namespace HelloGeneric4
{
    class Program
    {
        static void Main(string[] args)
        {
            // lambda 表達式
            //Func<double, double, double> func1 = (double a , double b) => { return a + b; };
            Func<double, double, double> func1 = (a, b) => { return a + b; };
            var result = func1(100.1, 200.2);
            Console.WriteLine(result);
        }
    }
}
           
c#