当我们在编程程序时,经常会遇到功能非常相似的模块,只是它们处理的数据不一样,除了分别写多个方法来处理不同数据,还可以利用泛型来简化这个过程,写一个方法,来解决不同参数传入的问题
普通方法与泛型方法区别
举栗子时间到
/// <summary>
/// 非泛型解决办法
/// </summary>
public class CommoneMethod
{
public static void ShowString(string Sparameter)
{
Console.WriteLine("This is {0},parameter type={1},value={2}",
typeof(CommoneMethod).Name, Sparameter.GetType().Name, Sparameter);
}
public static void ShowInt(int Sparameter)
{
Console.WriteLine("This is {0},parameter type={1},value={2}",
typeof(CommoneMethod).Name, Sparameter.GetType().Name, Sparameter);
}
public static void ShowDate(DateTime Sparameter)
{
Console.WriteLine("This is {0},parameter type={1},value={2}",
typeof(CommoneMethod).Name, Sparameter.GetType().Name, Sparameter);
}
/// <summary>
/// object是一切类型的父类,可以实现任一类型的转换
/// 但存在装箱与拆箱,降低程序性能
/// 装箱:将基本数据类型转换为一个对象类型 int a==>object a
/// 拆箱:将一个对象转换为基本数据类型 new Boolean()===>bool
/// </summary>
/// <param name="Sparameter"></param>
public static void ShowOb(object Sparameter)
{
Console.WriteLine("This is {0},parameter type={1},value={2}",
typeof(CommoneMethod).Name, Sparameter.GetType().Name, Sparameter);
}
}
/// <summary>
/// 泛型解决办法:解决多类型数据处理方法;延迟处理
/// 泛型语法:
/// show<T>(T parame);list<T>;class Myclass<>
/// T==>占位符,泛型在使用时决定T类型
/// </summary>
public class GenericsClass
{
public static void Show<T>(T Sparameter)
{
Console.WriteLine("This is {0},parameter type={1},value={2}",
typeof(CommoneMethod).Name, Sparameter.GetType().Name, Sparameter);
}
}
static void Main(string[] args)
{
Console.WriteLine("使用普通方法======》");
CommoneMethod.ShowInt(89);
CommoneMethod.ShowString("fgfb");
CommoneMethod.ShowDate(new DateTime());
Console.WriteLine("使用object方法======》");
CommoneMethod.ShowOb(89);
CommoneMethod.ShowOb("fgfb");
CommoneMethod.ShowOb(new DateTime());
Console.WriteLine("使用泛型方法======》");
//写法1
GenericsClass.Show<int>(99);
//写法2
GenericsClass.Show(25);
GenericsClass.Show("dzv");
GenericsClass.Show(new DateTime());
}
object是一切类型的父类,可以实现任一类型的转换,与泛型方法类似,可以用同一个方法解决不同数据类型的问题, 但object与具体数据类型的转化存在装箱与拆箱,会降低程序性能
装箱:将基本数据类型转换为一个对象类型 int a==>object a
拆箱:将一个对象转换为基本数据类型 new Boolean()===>bool
看个栗子:普通方法与泛型性能测试
普通方法与泛型性能测试
public static void ShowInt(int parame)
{
}
public static void ShowObject(Object parame)
{
}
public static void Show<T>(T parame)
{
}
/// <summary>
/// 性能测试
/// </summary>
public static void Test()
{
int value = 456;
long commonsecond = 0;
long objectsecond = 0;
long genericsecond = 0;
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < 100000000; i++)
{
ShowInt(value);
}
stopwatch.Stop();
commonsecond = stopwatch.ElapsedMilliseconds;
}
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < 100000000; i++)
{
ShowObject(value);
}
stopwatch.Stop();
objectsecond = stopwatch.ElapsedMilliseconds;
}
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < 100000000; i++)
{
Show(value);
}
stopwatch.Stop();
genericsecond = stopwatch.ElapsedMilliseconds;
}
Console.WriteLine("普通:{0},object:{1},泛型:{2}", commonsecond, objectsecond, genericsecond);
}
常用泛型举例
常用泛型:集合、字典
interface IStudent
{
}
public class Student : IStudent
{
public string name {
get; set; }
}
/// <summary>
/// 常用泛型:集合、字典
/// </summary>
public static void Test0()
{
//1.集合是可变数组
IList<Student> students = new List<Student>();
students.Add(new Student());
students.Add(new Student());
students.Add(new Student());
Student student0 = students[0];
//多态
IStudent student = new Student();
//2.字典
Dictionary<string, Student> myDictionary = new Dictionary<string, Student>();
myDictionary.Add("1001", new Student());
myDictionary.Add("1002", new Student());
myDictionary.Add("1003", new Student());
Student student2 = myDictionary["1001"];
//使用普通类型集合,当元素放入时会装箱为object类型,必须强制装换后才能使用
IList newSt = new ArrayList();
newSt.Add(new Student());
Student student1 = (Student)newSt[0];
student1.name = "普通";
}
泛型类 、泛型接口
泛型类在最近的项目中就有使用到:桌面端与API进行数据传输时,用json传输,json一般需要两个类来进行反序列化,第一个类为题头类,第二个类为数据类,那么由于数据类的不同,就需要把题头类写成泛型类
/// <summary>
/// 泛型类
/// </summary>
/// <typeparam name="T"></typeparam>
public class MyGenericlass<T>
{
public T _T;
}
#region 泛型接口
/// <summary>
/// 泛型接口
/// </summary>
/// <typeparam name="T"></typeparam>
public interface MyGenericInterface<T>
{
/// <summary>
/// T既是参数也可以是返回类型
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
T GetT(T t);
}
/// <summary>
/// 使用泛型接口时必须指定具体类型===>除非子类也是泛型类
/// </summary>
public class MyGenericInfClass : MyGenericInterface<string>
{
public string GetT(string t)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 子类也是泛型类则不用指定具体类型
/// </summary>
/// <typeparam name="T"></typeparam>
public class MyGenericInfClass0<T> : MyGenericInterface<T>
{
public T GetT(T t)
{
throw new NotImplementedException();
}
}
泛型约束
不使用泛型约束会产生类型不安全隐患
未使用泛型约束
public interface Isport
{
void Pingpang();
}
public interface IWork
{
void work();
}
public class People
{
public int Id {
get; set; }
public string Name {
get; set; }
public void Hi()
{
Console.WriteLine("Hi");
}
}
public class Chinese : People, IWork, Isport
{
public void Tradition()
{
Console.WriteLine("仁义礼智信");
}
public void SayHi()
{
Console.WriteLine("吃了么");
}
public void Pingpang()
{
Console.WriteLine("打兵乓球");
}
public void work()
{
throw new NotImplementedException();
}
}
public class Hubei : Chinese
{
public Hubei(int a)
{
}
public string Changjiang {
get; set; }
public void Majiang()
{
Console.WriteLine("打麻将");
}
}
public class Janpanse : Isport
{
public int Id {
get; set; }
public string Name {
get; set; }
public void Hi()
{
Console.WriteLine("Hi");
}
public void Pingpang()
{
Console.WriteLine("打兵乓球");
}
}
public static void ShowObje(object Sparameter)
{
Console.WriteLine("This is {0},parameter type={1},value={2}",
typeof(People).Name, Sparameter.GetType().Name, Sparameter);
Console.WriteLine($"{
((People)Sparameter).Id},{
((People)Sparameter).Name}");
}
public static void Test1()
{
People people = new People()
{
Id = 45,
Name = "加油"
};
Chinese chinese = new Chinese()
{
Id = 20,
Name = "最棒"
};
Hubei hubei = new Hubei(10)
{
Id = 12,
Name = "快乐"
};
Janpanse janpanse = new Janpanse()
{
Id = 89,
Name = "悔过"
};
ShowObje(people);
ShowObje(chinese);
ShowObje(hubei);
//此处会编译错误类型,因为Janpanse 并没有继承people类
ShowObje(janpanse);
}
使用泛型约束
值类型约束、引用类型约束、特定类型约束、无参数引用类型约束、多约束、方法使用约束
/// <summary>
/// 使用约束 储存的T类型必须是值类型
/// </summary>
/// <typeparam name="T"></typeparam>
public class Mylist<T> where T : struct
{
}
/// <summary>
/// 使用约束 储存的T类型必须是引用类型
/// </summary>
/// <typeparam name="T"></typeparam>
public class Mylist0<T> where T : class
{
}
/// <summary>
/// 使用约束 储存的T类型必须是Person类型或者Person子类
/// </summary>
/// <typeparam name="T"></typeparam>
public class Mylist1<T> where T : Person0
{
}
/// <summary>
/// 使用约束 储存的T类型必须是引用类型 new()储存的T类型必须有一个无参数构造函数
/// </summary>
/// <typeparam name="T"></typeparam>
public class Mylist2<T> where T : class, new()
{
}
/// <summary>
/// 多个约束
/// </summary>
/// <typeparam name="T"></typeparam>
public class Mylist3<T> where T : Person0, Box, Box0, new()
{
}
public class Person
{
public Person(string name, int a)
{
}
}
public class ChinesePerson : Person0, Box0, Box
{
}
public class PersonChilder : Person0
{
}
public interface Box
{
}
public interface Box0
{
}
public class Person0
{
public int Id {
get; set; }
public string Name {
get; set; }
public Person0()
{
}
}
public struct Animal
{
}
public enum myemun
{
}
public static void ShowObje_Generics<T>(T Sparameter) where T : Person0, new()
{
Console.WriteLine("This is {0},parameter type={1},value={2}",
typeof(People).Name, Sparameter.GetType().Name, Sparameter);
Console.WriteLine($"{
((Person0)Sparameter).Id},{
((Person0)Sparameter).Name}");
}
public static void Test2()
{
//值类型约束
new Mylist<int>();
new Mylist<long>();
new Mylist<Animal>();
//引用类型约束
new Mylist0<Person>();
new Mylist0<string>();
//特定引用类型
new Mylist1<Person0>();
new Mylist1<PersonChilder>();
//使用无参数引用类型
new Mylist2<Person0>();
new Mylist2<ChinesePerson>();
new Mylist2<PersonChilder>();
//多约束
new Mylist3<ChinesePerson>();
//方法使用约束
Person0 person0 = new Person0
{
Id = 45,
Name = "方法泛型约束"
};
ShowObje_Generics(person0);
}