C#【进阶】泛型
1、泛型
文章目录
1、泛型是什么
泛型实现了类型参数化,达到代码重用目的
通过类型参数化来实现同一份代码上操作多种类型
泛型相当于类型占位符
定义类或方法时使用替代符代表变量类型
当真正使用类或方法时再具体指定类型
2、泛型分类
泛型类和泛型接口
基本语法
class 类名<泛型占位字母>
interface 接口名<泛型占位字母>
泛型函数
基本语法
函数名<类型占位字母>(参数列表)
//泛型占位字母可以有多个,用逗号分开
3、泛型类和接口
TestClass<int> t = new TestClass<int>();
t.value = 1;
TestClass<string> t2 = new TestClass<string>();
t2.value = "ok";
TestClass2<int, string, float, bool> t3 = new TestClass2<int, string, float, bool>();
class TestClass<T>
{
public T value;
}
class TestClass2<T, M, L,Key>
{
public T Value;
public M GetM;
public L GetL;
public Key GetKey;
}
interface TestInsterface<T>
{
T vale
{
get;
set;
}
}
class Test : TestInsterface<int>
{
public int vale { get; set ;}
}
4、泛型方法
1、普通类中的泛型方法
Test2 test2 = new Test2();
test2.Fun<string>("ok");
class Test2
{
public void Fun<T>(T val)
{
Console.WriteLine(val);
}
public void Fun<T>()
{
//用泛型类型,做一些逻辑处理
T t = default(T);
}
public T Fun<T>(string test)
{
return default(T);
}
public void Fun<T,K,M>(T t, K k, M m){}
}
2、泛型类中的泛型方法
Test2<int> test3 = new Test2<int>();
test3.Fun(1.2f);
test3.Fun(true);
test3.Fun(10);
class Test2<T>
{
public T value;
//这个不是泛型方法,因为T是泛型类声明的时候就指定类型了
public void Fun(T t)
{
}
public void Fun<T>(T t) { }
}
5、泛型的作用
1、不同类型对象的相同逻辑处理就可以使用泛型
2、使用泛型可以一定程度避免装箱拆箱
例如:优化ArrayList
class ArrayList<T>
{
private T[] array;
public void Add(T value)
{
}
public void Remove(T value)
{
}
}
思考 泛型方法判断类型
//定义一个泛型方法,方法内判断该类型为何类型,并返回类型的名称与占有的字节数
//如果是int,则返回整形,4字节
//只考虑int,char,float,string,如果是其他类型,则返回其他类型
//可以通过typeof(类型) == typeof(类型)的方式进行类型判断
Console.WriteLine(Fun<int>());
Console.WriteLine(Fun<char>());
Console.WriteLine(Fun<float>());
Console.WriteLine(Fun<string>());
Console.WriteLine(Fun<bool>());
Console.WriteLine(Fun<uint>());
string Fun<T>()
{
if (typeof(T) == typeof(int))
{
return string.Format("{0},{1}字节","整形",sizeof(int));
}
else if (typeof(T) == typeof(char))
{
return string.Format("{0},{1}字节", "字符", sizeof(char));
}
else if (typeof(T) == typeof(float))
{
return string.Format("{0},{1}字节", "单精度浮点数", sizeof(float));
}
else if (typeof(T) == typeof(string))
{
return "字符串";
}
return "其他类型";
}
2、泛型约束
1、什么是泛型
让泛型的类型有一定的限制 where
1、值类型 where 泛型字母:stuct
2、引用类型where 泛型字母:class
3、存在无参公共构造函数where 泛型字母:new()
4、某个类本身或其派生类where 泛型字母:类名
5、某个接口的派生类型where 泛型字母:接口名
6、另一个泛型类型本身或者派生类where 泛型字母a:泛型字母b
2、各泛型约束
1、值类型
Test1<int> test1 = new Test1<int>();
test1.TestFun(1.2f);
class Test1<T> where T : struct
{
public T value;
public void TestFun<K>(K k) where K : struct
{
}
}
2、引用类型
Test2<Random> t2 = new Test2<Random>();
t2.value = new Random();
t2.TestFun(new Object());
class Test2<T> where T : class
{
public T value;
public void TestFun<K>(K k) where K : class { }
}
3、存在无参公共构造函数
Test3<Test1> t3 = new Test3<Test1>();
Test3<Test2> t4 = new Test3<Test2>();//必须是具有公共的无参构造函数的非抽象类型
class Test3<T> where T : new()
{
public T value;
public void TestFun<K>(K k) where K : new() { }
}
class Test1 { }
class Test2
{
public Test2(int i) { }
}
4、类约束
Test4<Test1> t4 = new Test4<Test1>();
Test4<Test2> t5 = new Test4<Test2>();
class Test4<T> where T : Test1
{
public T value;
public void TestFun<K>(K k) where K : Test1 { }
}
class Test1 { }
class Test2 : Test1
{
public Test2(int i) { }
}
5、接口约束
Test5<IFoo> t6 = new Test5<IFoo>();
Test5<Test1> t5 = new Test5<Test1>();
class Test5<T> where T : IFoo
{
public T value;
public void TestFun<K>(K k) where K : IFoo { }
}
interface IFoo { }
class Test1 : IFoo{ }
6、另一个泛型约束
Test5<Test1,IFoo> t6 = new Test5<Test1,IFoo>();
Test5<Test1, Test1> t7 = new Test5<Test1, Test1>();
class Test5<T,U> where T : U
{
public T value;
public void TestFun<K,V>(K k) where K : V { }
}
interface IFoo { }
class Test1 : IFoo { }
3、约束的组合使用
class Test7<T> where T : class,new(){}
4、多个泛型有约束
class Test8<T,K> where T:class,new() where K:struct{}
思考1 泛型实现单例模式
//用泛型实现一个单例模式基类
Test.Instance.value = 2;
GameMgr.Instance.value = 3;
class SingleBase<T> where T : new()
{
private static T instance = new T();
public static T Instance
{
get
{
return instance;
}
}
}
class GameMgr : SingleBase<GameMgr>
{
public int value = 10;
}
class Test
{
private static Test instance = new Test();
public int value = 10;
private Test() { }
public static Test Instance { get { return instance;} }
}
思考2 ArrayList泛型实现增删查改
//利用泛型知识点,仿造ArrayList实现一个不确定数组类型的类
//实现增删查改方法
ArrayList<int> array = new ArrayList<int>();
Console.WriteLine(array.Count);
Console.WriteLine(array.Capacity);
array.Add(1);
array.Add(2);
array.Add(4);
Console.WriteLine(array.Count);
Console.WriteLine(array.Capacity);
Console.WriteLine(array[1]);
Console.WriteLine(array[3]);
array.Remove(2);
Console.WriteLine(array.Count);
for (int i = 0; i < array.Count; i++)
{
Console.WriteLine(array[i]);
}
array[0] = 88;
Console.WriteLine(array[0]);
ArrayList<string> array2 = new ArrayList<string>();
class ArrayList<T>
{
private T[] array;
//当前存了多少数
private int count;
public ArrayList()
{
count = 0;
//开始容量为16
array = new T[16];
}
public void Add(T value)
{
//是否要扩容
if (count >= Capacity)
{
//每次扩容两倍
T[] newArray = new T[Capacity * 2];
for (int i = 0; i < Capacity; i++)
{
newArray[i] = array[i];
}
//重写指向地址
array = newArray;
}
//不需要扩容
array[count++] = value;
}
public void Remove(T value)
{
int index = -1;
//遍历存的值,而不是数组的容量
for (int i = 0; i < Count; i++)
{
if (array[i].Equals(value))
{
index = i;
break;
}
}
if (index != -1)
{
RemoveAt(index);
}
}
public void RemoveAt(int index)
{
if (index < 0 || index >= Count)
{
Console.WriteLine("索引不合法");
return;
}
//删除后,将空出来的位置前移
for (; index < Count - 1; index++)
{
array[index] = array[index + 1];
}
//把最后剩下的位置设为默认值
array[Count - 1] = default(T);
count--;
}
public T this[int index]
{
get
{
if (index < 0 || index >= Count)
{
Console.WriteLine("索引不合法");
return default(T);
}
return array[index];
}
set
{
if (index < 0 || index >= Count)
{
Console.WriteLine("索引不合法");
return;
}
array[index] = value;
}
}
/// <summary>
/// 获取容量
/// </summary>
public int Capacity
{
get
{
return array.Length;
}
}
/// <summary>
/// 得到具体存了多少值
/// </summary>
public int Count
{
get
{
return count;
}
}
}
原文地址:https://blog.csdn.net/AMrss/article/details/138751702
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!