1. Generics
Generics implement type parameterization to achieve code reuse.
Through type parameterization, the same code can operate on multiple types.
Generics are equivalent to type placeholders.
When defining a class or method, a substitute is used to represent the variable type.
When the class or method is actually used, the type is specified.
Basic syntax for generic classes and generic interfaces
:
class class name <generic placeholder letter>
interface interface name <generic placeholder letter>
public class test : MonoBehaviour
{
private void Start()
{
TestClass<int> testClass = new TestClass<int>();
Debug.Log(testClass.value);
TestClass2<int,string,bool> testclass2 = new TestClass2<int,string,bool>();
Debug.Log(testclass2.value);
}
}
class TestClass<T>
{
public T value;
}
class TestClass2<T, K, M>
{
public K key;
public M value;
public T Value { get; set; }
}
public interface TestInterface<T>
{
T Value { get; set; }
}
class TestGetInter : TestInterface<int>
{
public int Value { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
}
Basic syntax of generic functions
: function name <generic placeholder letter> (parameter list)
Note: There can be multiple generic placeholder letters, separated by commas
/// <summary>
/// 普通类里面的泛型方法
/// </summary>
public void testFun<T>(T value)
{
Debug.Log(value);
}
public void testFunc<T>()
{
//用泛型做逻辑处理
T t = default(T);
}
public T testFun<T>()
{
return default(T);
}
private void Start()
{
testFun<string>("12");
}
/// <summary>
/// 泛型类中的泛型方法
/// </summary>
public class test : MonoBehaviour
{
private void Start()
{
Test2<int> test = new Test2<int>();
//被限定了类型。函数只能传int
test.Func(1);
//Func2是真正的泛型方法
test.Func2("123");
test.Func2(false);
}
}
class Test2<T>
{
public T value;
/// <summary>
/// 这个不叫泛型方法,T在类已经定性了。
/// </summary>
public void Func<T>(T t) { Debug.Log(t); }
/// <summary>
/// 这个才是泛型方法
/// </summary>
public void Func2<K>(K k) { }
}
2. Generic constraints
Let the generic type have certain restrictions.
Keyword: where
There are 6 types of generic constraints
1. Value type where generic letter: struct
2. Reference type where generic letter: class
3. There is a parameterless public constructor where generic Type letter: new()
4. A certain class itself or its derived class where generic letter: class name
5. Derived type of an interface where generic letter: interface name
6. Another generic type itself or a derived type where generic letter: another generic letter
/// <summary>
/// 泛型类中的泛型方法
/// </summary>
public class test : MonoBehaviour
{
private void Start()
{
Test2<int> t1= new Test2<int>(); 值类型
t1.TestFunc<float> (1.3f);
Test3<System.Random> t2 = new Test3<System.Random>(); 引用类型
t2.TestFunc<int[]>(new int[5]);
//<Get2>必须是公共的无参数构造函数的非抽象类型
Test4<Get2> t3 = new Test4<Get2>(); 无参构造函数
Test5<Get2> t5 = new Test5<Get2>(); 类约束
Test6<IGet3> t6 = new Test6<IGet3>(); 接口约束
Test7<IGet4,IGet3> t7 = new Test7<IGet4,IGet3>(); 另一个泛型约束
//IGet4继承于IGet3
}
}
class Get2
{
public Get2(int a) { }
public Get2() { }
}
interface IGet3
{
}
interface IGet4 : IGet3
{
}
/// <summary>
/// 值类型约束
/// </summary>
class Test2<T> where T : struct
{
public T value;
public void TestFunc<K>(K k) where K : struct { }
}
/// <summary>
/// 引用类型约束
/// </summary>
class Test3<T> where T : class
{
public T value;
public void TestFunc<K>(K k) where K : class { }
}
/// <summary>
/// 无参构造函数
/// </summary>
class Test4<T> where T : new()
{
public T value;
public void TestFunc<K>(K k) where K : struct{ }
}
/// <summary>
/// 类约束
/// </summary>
class Test5<T> where T : Get2 //某个类或者其派生类
{
public T value;
public void TestFunc<K>(K k) where K : struct { }
}
/// <summary>
/// 接口约束
/// </summary>
class Test6<T> where T : IGet3 //某个接口或者其派生类/派生接口
{
public T value;
public void TestFunc<K>(K k) where K : struct { }
}
/// <summary>
/// 另一个泛型约束
/// </summary>
class Test7<T,U> where T : U //另一个泛型本身或者派生类
{
public T value;
public void TestFunc<K>(K k) where K : struct { }
}
Use combinations of constraints:
//new()要放在后面
class Test3<T> where T : class,new()
{
public T value;
public void TestFunc<K>(K k) where K : class { }
}
Multiple generics have constraints:
class Test2<T,M> where T : struct where M : struct
{
public T value;
public void TestFunc<K>(K k) where K : struct { }
}