.NET Knowledge Carding-1. Generic Generic

1. Generic

1.1 Introducing generics: deferred declaration

When a generic method is declared, the type is not written, and the type is specified when it is called.

Postponement statement: Postpone everything can be postponed.

1.2 How to declare and use generics

Generic method: add angle brackets after the method name, which contains type parameters

The type parameter is actually a type T declaration, the method can use this type T.

As follows:

public static void Show<T>(T t)

        {

            Console.WriteLine($"This is {typeof(CustomMethod)},paramater={t.GetType().Name},value={t}");

        }

1.3 Benefits and principles of generics

The performance of generic methods is the same as that of ordinary methods. When a method is declared by a generic, the type is not written. What type of T is. Only when it is called, do you know that a method can meet different types.

1.4 Generic class, generic method, generic interface, generic delegate

1.4.1 Generic types

One class meets different types of needs

details as follows:

public class BaseModel

    {

        public int Id { get; set; }

    }

    public class GenericClass<T>

        where T: BaseModel // is a generic base class constraint

    {

 

    }

1.4.2 Generic methods

One way to meet different types of needs

details as follows:

public static void Show<T>(T t)

        {

            Console.WriteLine($"This is {typeof(CustomMethod)},paramater={t.GetType().Name},value={t}");

        }

1.4.3 Generic interface

One interface meets different types of needs

   // Generic interface

    public interface IGenericInterface<T>

    {

        public void  SayHi(T t);

}

1.4.4 Generic delegation

One delegate meets different types of needs

public delegate void Do<T>(T t);

1.5 Generic constraints

Without constraints, generics will be very limited. There are 5 types of generic constraints. as follows:

1.5.1 Base class constraints

Where T:BaseModel

BaseModel can be used as a base class

Only objects of this type or objects derived from this type can be used as type parameters. (Seal constraints are not acceptable because they are meaningless.)

// Base class

    public class BaseModel

    {

        public int Id { get; set; }

    }

    // Generic class

    public class GenericClass<T>

        where T: BaseModel // is a generic base class constraint

    {

 

}

transfer:

  GenericConstraint.Show<BeiJing>(new BeiJing());

1.5.2 Reference type constraints

 

// Reference type constraints

        public static T Get<T>() where T:class

        {

            return default (T); // default is a keyword, according to the type T returns the corresponding default

        }

transfer:

GenericConstraint.Get<Person>(new Person());

1.5.3 Value type constraints

 

  // Value type constraints

        Public static D GetD<D>() where D:struct

        {

            return default(D);

        }

transfer:

GenericConstraint.GetD<int>(116);

1.5.4 No-argument constructor

 

// No parameter constructor constraint

        Public static S GetS<S>()

            where S: new () // Mealless constructor constraint

        {     

            return new S();

        }

transfer:

GenericConstraint.GetS<Chinese>();

1.5.5 Interface constraints

 

// Interface constraints

        public static void Show2<T>(T t) where T : ISports

        {

            t.Basketball();

        }

transfer:

GenericConstraint.Show2<USA>(new USA());

1.6 Covariance and Inversion

The so-called covariance and inversion are all related to generics (mostly used in interfaces).

1.6.1 Covariance

Decorate the return value

Let the right side use subclasses, making it easier to use generics (subclasses to parent classes)

Out modification, after covariation can only return results, not parameters

IEnumerable<Bird> birdList=new List<Sparrow>();

  // out covariant, can only return results (subclass to parent)

    public interface ICustomerListOut<out T>

    {

        T Get();

    }

 

    public class CustomerListOut<T>:ICustomerListOut<T>

    {

        public T Get()

        {

            return default(T);

        }

}

 

ICustomerListOut<Bird> list2 = new CustomerListOut<Sparrow>();

            Func<Bird> func = new Func<Sparrow>(() => null);

            IEnumerable<Bird> list3 = new List<Sparrow>();

1.6.2 Inverter

Modify incoming parameters

Make the parent class available on the right, making it easier to use generics (the parent rotor class)

In modified, can only be used as a parameter after inversion

// in Inverter can only be input parameter (parent rotor type)

    public interface ICustomerListIn<in T>

    {

        void Show(T t);

    }

    public class CustomerListIn<T>:ICustomerListIn<T>

    {

        public void Show(T t)

        {

            Console.WriteLine(t.GetType().Name);

        }

}

  // Inverter

            ICustomerListIn<Sparrow> list1 = new CustomerListIn<Bird>();

            Action<Sparrow> action = new Action<Bird>((i) => { });

 

public interface IMyList<in inT,out outT>

    {

        void Show(inT t);

        outT Get();

        outT Do(inT t);

    }

 

    public class MyList<T, T1> : IMyList<T, T1>

    {

        public void Show(T t)

        {

            Console.WriteLine(t.GetType().Name);

        }

 

        public T1 Get()

        {

            Console.WriteLine(typeof(T1).Name);

            return default(T1);

        }

 

        public T1 Do(T t)

        {

            Console.WriteLine(t.GetType().Name);

            Console.WriteLine(typeof(T1).Name);

            return default(T1);

        }

    }

   IMyList<Sparrow, Bird> myList1 = new MyList<Sparrow, Bird>();

    IMyList<Sparrow, Bird> myList2 = new MyList<Sparrow, Sparrow>();//协变

    IMyList<Sparrow, Bird> myList3 = new MyList<Bird, Bird>();//逆变

IMyList<Sparrow, Bird> myList4 = new MyList<Bird, Sparrow>();//逆变+协变

1.7 Generic cache

Generic cache, each type will generate a different copy (suitable for different types of scenarios that need to cache a piece of data)

  public class GenericCache<T>

    {

        private static string _TypeTime = "";

        static GenericCache()

        {

            Console.WriteLine ("This is GenericCache static constructor");

            _TypeTime = $"{typeof(T).FullName}_{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}";

        }

 

        public static string GetCache()

        {

            return _TypeTime;

        }

}

 

/// <summary>

    /// Dictionary cache: static attributes reside in memory

    /// </summary>

    public class DictionaryCache

    {

        private static Dictionary<Type, string> _TypeTimeDictionary = null;

        static DictionaryCache()

        {

            Console.WriteLine ("This is DictionaryCache static constructor");

            _TypeTimeDictionary = new Dictionary<Type, string>();

        }

        public static string GetCache<T>()

        {

            Type type = typeof(Type);

            if (!_TypeTimeDictionary.ContainsKey(type))

                _TypeTimeDictionary[type] = $"{typeof(T).FullName}_{DateTime.Now.ToString("yyyy-MM-dd HH mm:ss")}";

            return _TypeTimeDictionary[type];

        }

    }

Guess you like

Origin www.cnblogs.com/alannever/p/12723913.html