Revue des connaissances de base C# - 9. Génériques, contraintes génériques

1. Génériques

    Les génériques implémentent le paramétrage de type pour réaliser la réutilisation du code.
    Grâce au paramétrage de type, plusieurs types peuvent être exploités sur le même code.

    Les génériques sont équivalents aux espaces réservés de type.
    Lors de la définition d'une classe ou d'une méthode, un substitut est utilisé pour représenter le type de variable.
    Lorsque la classe ou la méthode est réellement utilisée, le type est spécifié.

    Syntaxe de base pour les classes génériques et les interfaces génériques
    :
    classe nom de la classe <lettre d'espace réservé générique>
    interface nom de l'interface <lettre d'espace réservé générique>

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(); }
}

    Syntaxe de base des fonctions génériques
    : nom de la fonction <lettre d'espace réservé générique> (liste de paramètres)

    Remarque : Il peut y avoir plusieurs lettres d'espace réservé génériques, séparées par des virgules.

/// <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. Contraintes génériques

Laissez le type générique avoir certaines restrictions.
Mot clé : où
Il existe 6 types de contraintes génériques
1. Type de valeur où lettre générique : struct
2. Type de référence où lettre générique : classe
3. Il existe un constructeur public sans paramètre où lettre de type générique : new ()
4. Une certaine classe elle-même ou sa classe dérivée où lettre générique : nom de classe
5. Type dérivé d'une interface où lettre générique : nom de l'interface
6. Un autre type générique lui-même ou un type dérivé où lettre générique : une autre lettre générique

/// <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 { }
}

Utilisez des combinaisons de contraintes :

//new()要放在后面
class Test3<T> where T : class,new()
{
    public T value;
    public void TestFunc<K>(K k) where K : class { }
}

Plusieurs génériques ont des contraintes :

class Test2<T,M> where T : struct where M : struct
{
    public T value;
    public void TestFunc<K>(K k) where K : struct { }
}

Je suppose que tu aimes

Origine blog.csdn.net/qq_29296473/article/details/131536896
conseillé
Classement