1: What is generic and generic usage plus covariant contravariance

1. What is generic?

就在在声明的时候,带上一个<>,指定类型参数,调用的时候指定类型调用---泛型;

concept

Concept that can be skipped directly.

  1. Generic method: one method satisfies different types of needs;

  2. Generic class: one class meets the needs of different classes;

  3. Generic interface: one interface meets the needs of different interfaces;

  4. Generic delegation: a delegation meets the needs of different delegations;

    Object is the parent class of all types.
    Any place where a parent class appears can be replaced by a subclass.

For example

下面代码段,这就是常用的泛型<>;就是说在传类型以前他可以是任何类型。传int或类等类或结构类型的时候就限定了他的类型。
List<int> intlist = new List<int>();
List<string> stringlist = new List<string>();

2. How to declare and use generics?

Code example and effect

public class Monitor
    {
    
    
        public static void Show()
        {
    
    
            Show<int>(1);
        }
        private static void Show<T>(T tParameter)
        {
    
    
            Console.WriteLine($"调用第一次泛型{tParameter}");
        }
    }

Code execution diagram

3. Generic delay thinking?

Try to be as specific as possible

When writing code, put the actual implementation content as far back as possible. Such a hazy program gives us many possibilities. For example, we can agree on what parameter it should be when we call.

4. The benefits and principles of generics?

benefit

  1. One method can meet different types of needs. (In a class, you need to pass parameters, int, string, etc., and you cannot write a new method for each different type of parameter. If you cannot achieve high availability and scalability, then you can use generics. Of course, Object can also be used here, but The speed will be as much as twice as slow, because it involves boxing and unboxing)
    Boxing is to convert "value type" to "reference type" (Object);
    unboxing is to convert "reference type" to "value type";
  2. High performance (its speed is the same as when using int, string and other structures or classes directly).

Principles and concepts

After generics are compiled, generic parameters will generate placeholders. 2
Finally, different ordinary methods will be generated according to the call;
generics have been released in .NetFramework2;
generics are not a syntactic sugar (syntactic sugar refers to adding a certain syntax, right The function of the language has no effect, which is convenient for programmers to use);
Generics—compiler upgrade + CLR upgrade
Generics are supported by the framework upgrade;

5. Generic classes, methods, interfaces, delegates?

concept

  1. Generic method: one method satisfies different types of needs;
  2. Generic class: one class meets the needs of different classes;
  3. Generic interface: one interface meets the needs of different interfaces;
  4. Generic delegation: a delegation meets the needs of different delegations;

6. Generic constraints, generic caching?

What constraints solve

When the incoming parameters are processed, the real type may not match.

Generic constraint classification

  1. Base class constraint: Constrain this T to be People; the constraint can only pass People or subclasses of People
  2. Interface constraint: The constraint that T is that the implementation class of ISports interface can call the method in the interface—right; when calling—only the class that implements this interface can be passed into—obligation
  3. Reference type constraints: only reference type parameters can be passed in
  4. Value type constraints: only value type parameters can be passed in
  5. Constraints on parameterless constructors: The parameters passed in must have a parameterless constructor and only need to write in the qualified type: new()

How to write constraints

By observing the following code segment. Only need to add
where T (parameter type) after the parameter: (qualified type) The
qualified type can be

		/// <summary>
        /// 值类型约束
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tParameter"></param>
        public static T ShowStruct<T>(T tParameter)
          where T : struct
        {
    
    
            return default(T);  //任何类型都可以,default(T) 根据实际的调用类来生成默认值;
        }
         
        /// <summary>
        ///引用类型约束
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tParameter"></param>
        public static T ShowClass<T>(T tParameter)
          where T : class
        {
    
    
            return default(T);  //任何类型都可以,default(T) 根据实际的调用类来生成默认值;
        }

constraint

Caching application scenarios

举例子:比如要进行根据实体类获取增删改查语句。这时候就可以用到缓存放起来。
/// <summary>
    /// 字典缓存:静态属性常驻内存
    /// </summary>
    public class DictionaryCache
    {
    
    
        private static Dictionary<Type, string> _TypeTimeDictionary = null;
        static DictionaryCache()
        {
    
    
            Console.WriteLine("This is DictionaryCache 静态构造函数");
            _TypeTimeDictionary = new Dictionary<Type, string>();
        }
        public static string GetCache<T>()
        {
    
    
            Type type = typeof(T);
            if (!_TypeTimeDictionary.ContainsKey(type))
            {
    
    
                //_TypeTimeDictionary[type] = string.Format("{0}_{1}", typeof(T).FullName, DateTime.Now.ToString("yyyyMMddHHmmss.fff"));  
                _TypeTimeDictionary[type] = $"{typeof(T).FullName}_{DateTime.Now.ToString("yyyyMMddHHmmss.fff")}";
            }
            return _TypeTimeDictionary[type];
        }
    }

7. Covariant contravariance?

concept

Covariance: Out can only be used as the return value, not as a parameter, and the right side can be used as a subclass.
Inverter: in can only be used as a parameter, not a return value, and the right side can be used as the parent class

use

The following code block will make an error, because we specify the generic type as Animal, and an error will occur when Cat is passed in as an instance.
Note: Cat is inherited from Animal

	
    #region 协变  逆变例子
    /// <summary>
    /// T 就只能做参数  不能做返回值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface ICustomerListIn<in T>
    {
    
    
       //T Get();
        void Show(T t);
    }

    public class CustomerListIn<T> : ICustomerListIn<T>
    {
    
    
        //public T Get()
        //{
    
    
        //    return default(T);
        //}
        public void Show(T t)
        {
    
    

        }
    }

    /// <summary>
    /// out 协变 只能是返回结果 
    /// 泛型T 就只能做返回值; 不能做参数; 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface ICustomerListOut<out T>
    {
    
    
        T Get();
       //void Show(T t); 
    }

    public class CustomerListOut<T> : ICustomerListOut<T>
    {
    
    
        public T Get()
        {
    
    
            return default(T);
        }

        //public void Show(T t)
        //{
    
    

        //}
    }

    public interface IMyList<in inT, out outT>
    {
    
    
        void Show(inT t);
        outT Get();
        outT Do(inT t);

        out 只能是返回值   in只能是参数
        //void Show1(outT t);//左边声明是父类---右边实例化是子类 new MyList<Cat, Cat>()---outT是cat--方法调用时以左边为准,传递的是animal的子类-狗
        //inT Get1(); 
    }

    /// <summary>
    /// out 协变 只能是返回结果 
    /// in  逆变 只能是参数
    /// 
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>

    public class MyList<T1, T2> : IMyList<T1, T2>
    {
    
    
        public void Show(T1 t)
        {
    
    
            Console.WriteLine(t.GetType().Name);
        }

        public T2 Get()
        {
    
    
            Console.WriteLine(typeof(T2).Name);
            return default(T2);
        }

        public T2 Do(T1 t)
        {
    
    
            Console.WriteLine(t.GetType().Name);
            Console.WriteLine(typeof(T2).Name);
            return default(T2);
        }
    }
    #endregion

8. A windfall?

reward

Hahahaha, I learned a new way to spell strings.
Add $ to the front of the splicing string, what parameters need to be added in the middle, type {} and put the parameters in it.

Console.WriteLine($"调用第一次泛型{tParameter}");

Guess you like

Origin blog.csdn.net/hello_mr_anan/article/details/107444182