当前位置:网站首页>C: generic reflection

C: generic reflection

2022-04-23 18:49:00 jackletter

1. Generic classes are templates for classes ( The runtime generally needs to be specific to use )

Generic classes are templates for classes , It cannot be used as a normal class , for instance : Cannot create instance .
as follows :

 public class Person<T>
 {
    
     public string Name {
     get; set; }
 }

This Person<T> It's a template for the class , It's not a normal class , therefore , Cannot create instance , Look below :
 Insert picture description here
What's confusing is : When writing code, it doesn't distinguish whether it is a generic class or not , such as :
 Insert picture description here
This NewInst<T> There is no fault in the method .

Actually ,NewInst<T> The reason why the method does not report an error , Because when the program is called , that T It's all set , In retrospect , Top note: is the code that was called before this? :
 Insert picture description here

That is, no matter how many layers the method is nested , At the end of the day T It must have been determined .

Look again : Person<Fu> and Person<Zi> Are there inheritance or implementation relationships between them ? Can be Person<Fu>
Assign a value to Person<Zi> Do you ?

First ,Person<Fu> and Person<Zi> They have no inheritance or implementation relationships , Except that they are materialized from a generic template , No other contact .
in addition , Under normal circumstances, the Person<Fu> Assign to or accept from Person<Zi> The variable of , But we may be able to use inversion and covariance , reference :《c#: Covariant and inverse depth analysis 》.

because Person<Fu> and Person<Zi> Not the same class , They have different Type example , So the following usage will lead to unexpected results :
 Insert picture description here

2. Generic methods are templates for methods ( The runtime generally needs to be specific to use )

Like generic classes , Generic methods cannot be used directly , Such as :
 Insert picture description here
If you want to run , For example, will T Materialization is the only way , as follows :
 Insert picture description here
Same as generic class , No matter how many layers our method is nested , When you run this method , It must have been embodied .

3. Special application scenarios of generic classes

A generic class is a template class , It cannot be instantiated and called as a normal class , But it is very useful when writing frameworks , such as :

stay asp.net core When you inject it :
 Insert picture description here

4. How to reflect and materialize a generic class 、 Generic methods

public class Class2
{
    
    public static void Main()
    {
    
        // Reflection generic class 
        var type = typeof(Person<>);
        Console.WriteLine($"type.IsGenericType={
      type.IsGenericType}");
        Console.WriteLine($"type.Name={
      type.Name}");
        // Materialization of generic classes 
        var type2 = type.MakeGenericType(typeof(int));
        var personInt = Activator.CreateInstance(type2);

        // Reflection generic method 
        var method = typeof(Class2).GetMethod("Test", new[] {
     typeof(IEnumerable<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), Type.MakeGenericMethodParameter(0) });
        Console.WriteLine($"method.IsGenericType={
      method.IsGenericMethod}");
        Console.WriteLine($"method.Name={
      method.Name}");
        // Materialization of generic methods 
        var method2 = method.MakeGenericMethod(typeof(int));
        method2.Invoke(null, new object[] {
     new List<int>(), 1 });

        Console.ReadLine();
    }
    public static void Test<T>(IEnumerable<T> list, T t) => Console.WriteLine($"t={
      t},list.Count={
      list.Count()}");
    public static void Test<T>() => Console.WriteLine("ok");
}

public class Person<T> {
     }

Running effect :
 Insert picture description here

版权声明
本文为[jackletter]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231847116154.html