0
点赞
收藏
分享

微信扫一扫

C#编程:泛型编程


C#编程:泛型编程_泛型


本篇目录

  • ​​泛型编程的定义​​
  • ​​泛型编程的示例​​
  • ​​简单示例:商品和盒子​​
  • ​​简单示例:学生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();
}
}
}

待拓展

泛型类说明

泛型方法说明

泛型接口说明

泛型委托说明



举报

相关推荐

0 条评论