什麼是泛型,泛型有什麼作用?
- 泛化的類型 , 與具體的相對 。
- 将具體的變為一般的 ,根據需求進行特化。
- 避免了類的膨脹、 成員膨脹的問題。
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);
}
}
}