本篇目錄
- 泛型程式設計的定義
- 泛型程式設計的示例
- 簡單示例:商品和盒子
- 簡單示例:學生ID
- 簡單示例:資料粘合運算
- 泛型委托(系統自帶)
- Action無傳回值泛型委托
- Func有傳回值泛型委托
- 泛型委托與Lambda表達式
- 待拓展
- 泛型類說明
- 泛型方法說明
- 泛型接口說明
- 泛型委托說明
泛型程式設計的定義
泛型程式設計解決的兩個問題:類型膨脹和成員屬性膨脹
泛型程式設計的示例
簡單示例:商品和盒子
泛型簡單示例:比如小商城裡面對于每一種商品都有一盒子來包裝,但是如果為每一種商品都定義一種盒子去實作包裝,那麼就造成類型膨脹。但是如果都使用一種盒子去實作,而在使用時對商品類型做判斷,那麼就會造成實作盒子包裝的類裡面的成員屬性膨脹。這兩種方式都不是最優解,最優解是通過泛型程式設計來特化商品所需要的盒子,這樣需要包裝是商品的盒子就會在使用的時候,自動特化成特定類型的盒子。
using System;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Apple ap = new Apple() { color="red"};
Book bo = new Book() { name="new book"};
Box<Apple> box1 = new Box<Apple>() { Cargo = ap };
Box<Book> box2 = new Box<Book>() { Cargo = bo };
System.Console.WriteLine(box1.Cargo.color);
System.Console.WriteLine(box2.Cargo.name);
System.Console.WriteLine("Hello World!");
System.Console.ReadKey();
}
public class Apple {
public string color { set; get; }
}
public class Book {
public string name { set; get; }
}
public class Box<T> {
public T Cargo { set; get; }
}
}
}
簡單示例:學生ID
泛型接口的實作,示例1
假如每個學生都需要有一個ID,那麼可以泛型一個ID接口,實作學生的類可以使用這個接口去實作學生的ID,ID的範圍可以根據具體要求而設定,比如下面示範的int 和ulong兩種資料類型。
using System;
namespace 泛型接口
{
class Program
{
static void Main(string[] args)
{
Student<int> stu1 = new Student<int> { };
stu1.ID = 101;
stu1.Name = "孫悟空";
Student<ulong> stu2 = new Student<ulong> { };
stu2.ID = 20000000000000002;
stu2.Name = "豬八戒";
Console.WriteLine("Hello World!");
System.Console.ReadKey();
}
interface StuID<Tid> {
Tid ID { set; get; }
}
class Student<Tid> : StuID<Tid> {
public Tid ID { set; get; }
public string Name { set; get; }
}
}
}
簡單示例:資料粘合運算
從以下例子可以看出,但做類似資料粘合的算術運算而沒有使用泛型程式設計的時候,會受到資料類型的制約,以下實作的方法中隻能對于int型數組進行粘合,但是對于double型數組卻無法實作,如果再去實作一個double類型的數組粘合方法,則程式會變得臃腫。
因為方法是類的成員,此時會出現了方法膨脹。
using System;
namespace 資料粘合zip
{
class Program
{
static void Main(string[] args)
{
int[] a1 = {1, 2, 3, 4, 5 };
int[] a2 = {1, 2, 3, 4, 5, 6 };
double[] a3 = { 1.1, 2.2, 3.3, 4.4, 5.5};
double[] a4 = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 };
var result = Zip(a1, a2);
System.Console.WriteLine(string.Join(',',result));
Console.WriteLine("Hello World!");
System.Console.ReadKey();
}
static int[] Zip(int[] a, int[] b)
{
int[] zipped = new int[a.Length + b.Length];
int a1 = 0, b1 = 0, z1 = 0;
do
{
if (a1 < a.Length)
zipped[z1++] = a[a1++];
if (b1 < b.Length)
zipped[z1++] = b[b1++];
} while (a1 < a.Length || b1 < b.Length);
return zipped;
}
}
}
如果使用了泛型程式設計,則上面這個例子的問題就可以解決。因為泛型對于資料類型有自動推算功能。
using System;
namespace 資料粘合zip
{
class Program
{
static void Main(string[] args)
{
int[] a1 = {1, 2, 3, 4, 5 };
int[] a2 = {1, 2, 3, 4, 5, 6 };
double[] a3 = { 1.1, 2.2, 3.3, 4.4, 5.5};
double[] a4 = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 };
var result = Zip(a1, a2);
System.Console.WriteLine(string.Join(',',result));
var result2 = Zip(a3, a4);
System.Console.WriteLine(string.Join(',', result2));
Console.WriteLine("Hello World!");
System.Console.ReadKey();
}
static T[] Zip<T>(T[] a, T[] b)
{
T[] zipped = new T[a.Length + b.Length];
int a1 = 0, b1 = 0, z1 = 0;
do
{
if (a1 < a.Length)
zipped[z1++] = a[a1++];
if (b1 < b.Length)
zipped[z1++] = b[b1++];
} while (a1 < a.Length || b1 < b.Length);
return zipped;
}
}
}
泛型委托(系統自帶)
泛型委托。最常見的泛型委托為:
Action泛型委托(無傳回值)
Func泛型委托(有傳回值)
Action無傳回值泛型委托
Action泛型委托示例
using System;
namespace 泛型委托
{
class Program
{
static void Main(string[] args)
{
Action<string> a1 = Say;
a1("安琪拉");
Action<int> a2 = MUl;
a2(1);
Console.WriteLine("Hello World!");
System.Console.ReadKey();
}
static void Say(string str) {
System.Console.WriteLine($"hello {str} !");
}
static void MUl(int x) {
System.Console.WriteLine(x*100);
}
}
}
Func有傳回值泛型委托
Func泛型委托示例
Func中最後一個參數表示傳回值類型,前面參數為參數類型
using System;
namespace 泛型委托
{
class Program
{
static void Main(string[] args)
{
Func<int, int, int> func1 = add;
var ret = func1(100, 200);
Func<double, double, double> func2 = add;
var ret2 = func2(10.2, 10.3);
System.Console.WriteLine(ret);
System.Console.WriteLine(ret2);
System.Console.WriteLine("Hello World!");
System.Console.ReadKey();
}
static int add(int a, int b) {
return a + b;
}
static double add(double a, double b) {
return a + b;
}
}
}
泛型委托與Lambda表達式
泛型委托與Lambda表達式
Lambda表達式也就是對于類似以上這種非常簡單的方法,不想去聲明它,而是在使用的時候,随時調用随時聲明,而且是匿名的聲明,這樣就可以避免極其簡單的方法對于程式的污染。 示例如下
using System;
namespace 泛型委托
{
class Program
{
static void Main(string[] args)
{
Func<double, double, double> func = (double a, double b)=> { return a + b; };
//這塊為Lambda表達式
//簡化後 Func<double, double, double> func = (a, b)=> { return a + b; };
var ret = func(10.2, 10.3);
System.Console.WriteLine(ret);
System.Console.WriteLine("Hello World!");
System.Console.ReadKey();
}
}
}