Generic generic [why, how is the performance of object compared with common methods? Generic class, generic method, generic interface, generic delegate, generic constraint, covariant inversion, generic cache]

Time:2020-11-14

1、 Why: why do we use generics?

Let’s take a look at this example first: we print the writing of different types of values

/// 
        ///Print an int value
        /// 
        public static void ShowInt(int iValue)
        {
            Console.WriteLine("This is ShowInt,parameter={0},type={1}", iValue, iValue.GetType().Name);
        }

        /// 
        ///Print a value of type string
        /// 
        public static void ShowString(string sValue)
        {
            Console.WriteLine("This is ShowString,parameter={0},type={1}", sValue, sValue.GetType().Name);
        }

        /// 
        ///Print people class
        /// 
        public static void ShowPeople(People people)
        {
            Console.WriteLine("This is ShowPeople,parameter={0},type={1}", people, people.GetType().Name);
        }
/*Common methods, objects, and methods in generic call parameters all come from the secondary definition * / int Ivalue = 20201026;
            String svalue = generic generic;
            People people = new People()
            {
                Age = 11, name = Test
            };

            /*General method*/
            Console.WriteLine ("--- General method: --- ---");
            Common.ShowInt(iValue);
            Common.ShowString(sValue);
            Common.ShowPeople(people);

result:

Thinking 1:Is it possible to define a method every time a type is needed? Then we need many different types. What is the difference between the above methods? How can we write only one method and call different types at the same time?

1. Different parameters and different parameter types make it impossible to call the same one,

Thinking 2: how to write a method that can be called by different types? In version 1.0, there was no concept of generics, so what to do?

Why can I pass int and string at the same time? We said: object type is the parent of all typesAt the same timeIn the object-oriented features:

Inheritance: C ා inheritance of the three major features, subclass has all the attributes and methods of the parent class;

Richter’s substitution principle: any parent class can be replaced by a subclass. Can we optimize it to the following writing method;

/// 
        ///C ා inheritance in the three major features, subclass has all the attributes and methods of the parent class, lees replacement principle: any parent class can be replaced with a subclass
        ///The object type is the parent of all types
        /// 
        public static void ShowObject(Object oValue)
        {
            Console.WriteLine("This is ShowObject,parameter={0},type={1}", oValue, oValue.GetType().Name);
        }
/*Common methods, objects, and methods in generic call parameters all come from secondary definitions*/
int iValue = 20201026;
            String svalue = generic generic;
            People people = new People()
            {
                Age = 11, name = Test
            };
            Console.WriteLine("--------------------object-----------------------");
            Common.ShowObject(iValue);
            Common.ShowObject(sValue);
            Common.ShowObject(people);

Is the result the same: using the object type meets our requirements and solves the reusability of the code

So I said before【 https://www.cnblogs.com/wangwangwangMax/p/5425361.html 】,Array, object and string are reference types. Their values are stored in the heap, and all value types are stored in the stack. If object type is used, there will be problems of boxing and unboxing and performance loss

When Microsoft introduced generics in C ා 2.0, it can solve the above problems very well. Let’s write a generic method to compare.

1 writing structure: there is a < > angle bracket after the method, eg: showlist (t value). The type parameter t is actually a type declaration, indicating that it is a placeholder. You can also use any non reserved words, eg: s or w
/// 
        ///Declare a generic method
        ///Structure: method is followed by a < > angle bracket showlist (t value)
        /// 
        ///Typeparam: type parameter, t is actually a type declaration, indicating that it is a placeholder, and any non reserved word can be used
        ///Param: parameter
        ///It is because of not writing death that it has unlimited possibilities
        public static void ShowList(T Value)
        {
            Console.WriteLine("This is ShowList,parameter={0},type={1}", Value, Value.GetType().Name);
        }
/*Common methods, objects, and methods in generic call parameters all come from secondary definitions*/
int iValue = 20201026;
            String svalue = generic generic;
            People people = new People()
            {
                Age = 11, name = Test
            };
Console.WriteLine ("--- declaration and use of generics --------");
            Generic.ShowList(iValue);
            Generic.ShowList(sValue);
            Generic.ShowList(people);

The above calls can also be written in the following format:

            Generic.ShowList(iValue);
            Generic.ShowList(sValue);
            Generic.ShowList(people);

If you can infer from the type of the parameter, you can omit the type parameter. This function provided by the compiler is called syntax sugar

result:

In this place, we only specify the specific type when calling the generic method;

Conclusion: [generic speaking is one thing, completing what can be done by many things before]

2、 How does generics work?

Generic principle: I don’t know what type it is. It is used when compiling【Place holder – ` 1, ` 2]

When calling, you can specify the specific parameter type

  Idea: [delay statement: postpone everything that can be postponed, and do what can be done later]

3、 What about the performance of the three?

Let’s write a test example,

Generic generic [why, how is the performance of object compared with common methods? Generic class, generic method, generic interface, generic delegate, generic constraint, covariant inversion, generic cache]Generic generic [why, how is the performance of object compared with common methods? Generic class, generic method, generic interface, generic delegate, generic constraint, covariant inversion, generic cache]

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnGenericFirst1
{
    /// 
    ///Performance test
    /// 
    public class Monitor
    {
        public static void Show()
        {
            Console.WriteLine("--------------------Monitor-----------------------");
            int iValue = 20201031; string sValue = "20201031";
            long commonSecond = 0;
            long objectSecond = 0;
            long genecirSecond = 0;

            {
                Stopwatch watch = new Stopwatch();
                watch.Start();
                for (int i = 0; i < 100_000_000; i++)
                {
                    ShowInt(iValue);
                }
                watch.Stop();
                commonSecond = watch.ElapsedMilliseconds;
                Console.WriteLine (100 million cycles, ordinary methods need {0} MS ", commonsecond);
            }

            {
                Stopwatch watch = new Stopwatch();
                watch.Start();
                for (int i = 0; i < 100_000_000; i++)
                {
                    // intList.Add (i) ; // public virtual int add (object value); there is boxing and unboxing operation
                    Showobject (Ivalue); // there is boxing and unboxing operation                    
                }
                watch.Stop();
                objectSecond = watch.ElapsedMilliseconds;
                Console.WriteLine (100 million cycles, object needs {0} MS ", objectsecond);
                ShowObject(sValue);
                //When you add a data type (showarint), you can't insert another data type+
                //"Compared to better ensure the call of declaration type, security");
            }

            {
                Stopwatch watch = new Stopwatch();
                watch.Start();
                List intList = new List();//iValue
                for (int i = 0; i < 100_000_000; i++)
                {
                    // intList.Add (i) ; // public void add (t item); generic methods under generic classes
                    Show(iValue);
                }
                watch.Stop();
                genecirSecond = watch.ElapsedMilliseconds;
                Console.WriteLine (100 million cycles, generics need {0} MS ", genecirsecond);
            }
        }

        #region privateMethod
        private static void ShowInt(int iParameter)
        { 
        }
        private static void ShowObject(object iParameter)
        {
        }
        private static void Show(T tParameter)
        {
        }
        #endregion

    }
}

For common methods, the performance test of object and generics can be viewed by clicking + on the left

Console.WriteLine ("--- General methods, object and generic performance testing --------");
            Monitor.Show();

result:

 

Conclusion: the performance of generic method is the same as that of common method, and it is the best. Moreover, it can satisfy multiple different types at the same time. Compared with object, generic method is safer

4、 Generic class + class name+

Above, we talked about generic methods. Next, let’s talk about generic classes, structures, class + class names+

///A class to meet different types of needs
    public class GenericClass
    {
        /// 
        ///Show if a type is declared in a class, there is no need to declare it again in a method. Here are two extensions of writing methods
        /// 
        ///Show s, s, t, t, W, w can also be lowercase. S, t come from generic classes, w comes from generic methods
        public static void Show(S s,T t,W w)
        {
        }
        public static void Show(S s, T t)
        {
        }
        public static void Show()
        {
        }
    }

5、 Generic interface, interface + interface name+

/// 
    ///Generic interface: no public static
    ///One interface meets different types of requirements;
    /// 
    /// 
    /// 
    public interface IGenericInterface
    {
        void Show(X x, Y y, W w);

        void Show(X x, Y y);
        void Show();
        //The return value of a generic type
        X GetT(X x);
    }

6、 The structure of a generic delegate is similar: delegate + return value + naming+

/// 
    ///Generic delegation: one delegate meets different types of needs
    /// 
    /// 
    /// 
    public delegate void DoSomethingHandler();

7、 Generic class, interface inheritance

public class GenericClassChild2 : GenericClass
    {
    }

Thinking: referring to the above column child, the code has not been compiled and inherits a generic parent class. Why does this method report errors?

The subclass genericclasschild2 does not have a generic concept [non generic, closed / common class: all types are determined], and it does not know the parent class [non closed type / open type: generic type is not specified]The type must be determined when calling,

If the parent class is an unclosed type, it cannot be used as the parent class of an enclosed type. You can specify the parent class as a specific type. The following method can inherit the parent class

/// 
    ///Inheritance instance 1 of generic class
    ///
public class GenericClassChild2 : GenericClass
    {
    }
/// 
    ///Inheritance instance 2 of generic class
    /// 
    public class GenericClassChild1 : GenericClass
    {
    }
/// 
    ///Inheritance instance 3 of a generic class -- the parent class is a closed type (if the specified type is not a generic class), that is, a normal type, and the subclass is a generic type, which can have 
    /// 
    public class GenericClassChild2 : GenericClass
    {
    }
/// 
    ///The inheritance principle of generic interface is the same as that of generic class inheritance
    /// 
    public interface IGenericInterfaceChild1: IGenericInterface
    { 
    }
    public interface IGenecirInterfaceChild2 : IGenericInterface
    { 
    }
    public interface IGenecirInterfaceChild2 : IGenericInterface
    {
    }

8、 Generic constraints

A generic object can be used as multiple things to satisfy different parameter types. It is without constraints. Any type can be passed in. We do not know what it is. Therefore, we will have some concepts of constraints. There are totally 5 types of generic constraints

Why use constraints? Let’s take a look at the following example:

Generic generic [why, how is the performance of object compared with common methods? Generic class, generic method, generic interface, generic delegate, generic constraint, covariant inversion, generic cache]Generic generic [why, how is the performance of object compared with common methods? Generic class, generic method, generic interface, generic delegate, generic constraint, covariant inversion, generic cache]

1     /// 
 2 // people entity
 3     /// 
 4     public class People
 5     {
 6         public int Id { get; set; }
 7         public int Age { get; set; }
 8         public string Name { get; set; }
 9         public void SayHi() 
10         {
11             Console.WriteLine("Hi, {0} Good,Morning!",this.Name);
12         }
13     }
14 
15     /// 
16 // Chinese entity
17     /// 
18     public class Chinese : People,iSports
19     {
20         public string KangFu { get; set; }
21         public string Characteristic { get; set; }
22         public void Pingpang()
23         {
24             Console.WriteLine("Pingpang");
25         }
26         public void Majiang()
27         {
28             Console.WriteLine("Majiang");
29         }
30     }
31 
32     public class Japanese : iSports
33     {
34         public int Id { get; set; }
35         public string Name { get; set; }
36 
37         public void Pingpang()
38         {
thirty-nine Console.WriteLine ("playing table tennis");
40         }
41     }
42 
43     /// 
44 // interface
45     /// 
46     public interface iSports
47     {
48         void Pingpong();
49     }

Entity class to be used

/// 
        ///Showobject method
        /// 
        /// 
        public static void ShowObject(Object oValue)
        {
            Console.WriteLine("This is {0},parameter={1},type={2}", typeof(GenecirConstraint), oValue, oValue.GetType().Name);
            People people = (People)oValue;
            Console.WriteLine("This is {0},people.Id={1},people.name={2}", typeof(GenecirConstraint), people.Id, people.Name);
            people.SayHi();
        }
Chinese chinese = new Chinese()
                {
                    Id = 5,
                    Name = Hunan
                };
                Japanese japanese = new Japanese()
                {
                    Id = 6,
                    Name = "Fukuhara Ai"
                };
                GenecirConstraint.ShowObject(chinese);
                GenecirConstraint.ShowObject(japanese);

Thinking 1: why does the code above report errors?
Because the object method can enter and exit any type, there is no restriction. If the incoming types do not match, an exception (type safety problem) will occur. Just like traffic, traffic regulations and traffic lights make it safer

2. Think about 2: why why can ordinary methods directly call properties and methods in the people class? Why can’t generics? –Because it is restricted, how can I make generics call properties and methods in the people class? In this case, we use generic constraints

[where: t class name]

/// 
    ///Generic constraints: no freedom without constraints
    ///Generic constraints can be used after generic classes, generic interfaces, and generic delegates
    ///Structure: Show (after S + where) declaration type s: [(s value) where s:] indicates that the generic "s" must satisfy the constraint of this people
    ///Where t: basemodel
    ///
/// 
        ///This is a base class constraint, which has two characteristics
        ///The first feature: we can regard t as a base class, and we can directly use its properties and methods - with constraints, we will have power; // if we simply pass a people, then the performance is no different from the ordinary methods in the above example, but using generics will be more flexible
        /// 
        public static void Show(S sValue) where S:People
        {
            Console.WriteLine("This is Show,parameter={0},type={1}", sValue, sValue.GetType());
            Console.WriteLine("This is Show,people.Id={0},people.name={1}", sValue.Id,sValue.Name);
            sValue.SayHi();
        }

Thinking: why call this method and pass in aIvalue, svalue, it will report an error, but people will not?

                               

Console.WriteLine ("--- calls to generic base class constraints --------";
                GenecirConstraint.Show(people);
                GenecirConstraint.Show(new Chinese()
                {
                    Id = 1,
                    Name = Chongqing,
                    Characteristic: "Chongqing hot pot"
                });
                //Type parameters can be directly removed without writing, and the compiler will automatically calculate
                GenecirConstraint.Show(new Chinese()
                {
                    Id = 2,
                    Name = Shanghai,
                    Characteristic: "Shanghai chaos"
                });
Console.WriteLine "Conclusion: the second major feature of the generic base class constraint is that it or its subclass can only be passed in when it is called.");

result:

2. Generic interface constraint: [: where t interface name]

/// 
        ///Interface constraints, only methods in the interface can be used
        /// 
        /// 
        /// 
        public static void Sports(S sValue) where S : iSports
        {
            Console.WriteLine("This is Show,parameter={0},parameter={1}", sValue, sValue.GetType().Name);
            sValue.Pingpang();
        }
Console.WriteLine ("--- generic interface constraint calls: --- ---");
                GenecirConstraint.Sports(new Chinese()
                {
                    Id = 3,
                    Name = Beijing,
                    Characteristic: "Beijing roast duck"
                }); // in the entity class, Japanese inherits isports, so you can call this method
                GenecirConstraint.Sports(japanese);
                //In the entity class, the people class does not inherit the isports interface, so this method cannot be called
                //GenecirConstraint.Sports(people);

result:

    public interface iDaily
    {
        void Majiang();
    }
/// 
        ///Constrained by both a class and an interface: base class in front, interface in the back
        ///Can only be constrained by one parent class, but can be constrained by multiple interfaces
        /// 
        /// 
        /// 
        public static void ClassInterFaseMeanwhile(S sValue) where S : People, iSports, iDaily
        {
            Console.WriteLine("This is Show,parameter={0},parameter={1}", sValue, sValue.GetType().Name);
            Console.WriteLine("This is Show,people.Id={0},people.name={1}", sValue.Id, sValue.Name);
            sValue.SayHi();
            sValue.Pingpang();
            sValue.Majiang();
        }
Console.WriteLine ("--- generic base class and interface constraint are called simultaneously: --- ---");
       GenecirConstraint.ClassInterFaseMeanwhile(chinese);

result:

3. In addition to generic class constraints and interface constraints, there are three basic constraints, which are more special: reference type constraint, value type constraint, and parameterless constructor constraint

/// 
        ///Reference type constraint: [where t: class, t must be a reference type]
        ///Where t: string // the inner constraint of the seal is invalid, because it is meaningless
        /// 
        /// 
        public static T GetT() where T : class //T tParameter
        {
            Return null; // all reference types can return null. If there is no where t: class constraint, an error will be reported. It may also be a value type
        }

        /// 
        ///Value type constraint: [where t: struct]
        /// 
        public static T GetValuetype(T tParameter) where T : struct
        {
            //Return 0; // why is an error reported when 0 is returned here? The value type is not only int, but also other types, eg: long integer, decimal
            Return default (T); // default is a keyword that gets a default value based on the type of T
        }

        /// 
        ///No parameter constructor constraint [where t: new()]
        /// 
        /// 
        /// 
        public T GetParameterlessConstructor() where T : new()
        {
            return new T();//
        }
/// 
        ///Several constraints can be superimposed and separated with a tease
        ///If there are multiple parameters, the constraint can be written directly without using commas
        /// 
        /// 
        public static T Getconstraint() 
            Where t: Chinese, isports, idaily, new() // class meaningless
            where S:class
        {
            return new T();//
        }

9、 Covariant inversion

1. What is covariant inversion? Background? What is its premise and what can it do?

1. Covariant inversion: generic delegation and generic interface are preceded by in and out, so it is called covariant inversion of generics. Let’s continue to look at examples below

//It defines an entity class of animals 
       public class Animal
        {
            public int Id { get; set; }
        }
       //Define an entity class of cat, inherit animal class
        public class Cat:Animal
        {
            public string Name { get; set; }
        }

2. Background:

When we write code, will we encounter such a situation? This is the common method of writing

{
                Animal animal1 = new Animal();
                Animal animal2 = new cat(); // the parent variable is instantiated with subclass, and cats are of course animals
                Cat cat1 = new Cat();
                //Cat cat2 = new animal(); // subclass variable cannot be instantiated with parent class
                //The place where the father appears can be replaced by the child, while the place where the child appears can not be replaced by the parent. Cats belong to animals, and animals are not necessarily only cats
            }

But when we write in generics, why is it wrong? Why?

//Of course, we can do it in this way
List animals3 = new List().Select(c => (Animal)c).ToList();
1 / * according to the logic of the common method above, cats belong to animals, but why not? Why not? * /
2 // list is a class, and list is also a class. As mentioned above, when compiling generics, it is just a place holder, and it is determined when it is called. It is confirmed that it is a list,
3 // and then list. There is no parent-child relationship between them. List doesn't matter
4 // in other words: you are a list instance and I am a list instance. We are not inherited, so we can't
5 // if the syntax fails, it can be semantically. This is the background of covariant inversion
7 // we use generics for the convenience of writing

3. Covariant IEnumerable out Covariant covariant modify return value effect: let the right side can use subclass condition: t can only return results, can not be used as a parameter

/*--------------------------------------------------Covariant out----------------------------------------------------*/
        /// 
        ///Out covariant t can only be used as return value, not as parameter
        /// 
        /// 
        public interface ICustomerListOut
        {
            //void Show();
            //Void show (T, t); // covariant t can only be used as return value, not as parameter
            T get(); // return value of generic type
        }

        /// 
        ///In this case, the generic class inherits the interface
        /// 
        /// 
        public class CustomerListOut : ICustomerListOut
        {
            public T Get()
            {
                return default(T);
            }
        }
/*--------------------------------------------------Covariant out----------------------------------------------------*/
            {
                //public interface IEnumerable : IEnumerable
                //Covariant: IEnumerable condition: t can only return the result, it can not be used as a parameter
                //The covariant function is to prevent the failure of the parent-child inheritance relationship after the generic packaging, and further strengthen the convenience of generics
                IEnumerable animals1 = new List();
                IEnumerable animals2 = new List();

                //We have defined an interface that supports covariance. Can we also use this interface to define a cat class that supports covariance
                //Limitation: after out modifies covariance, t can only be used as a return value, not as a parameter
                //On the left is a defined interface that supports covariance, and on the right is a generic class that inherits the covariant interface
                ICustomerListOut customerList1 = new CustomerListOut();
                ICustomerListOut customerList2 = new CustomerListOut();
            }

4. Inverter inContravariant modifies the input parameter. Contravariant: let the right side use the parent class. After in modifies the inversion, t can only be used as a parameter, not as a return value

Inverter in----------------------------------------------------*/
 2         public interface ICustomerListIn
 3         {
 4 // T get(); // inverse t cannot be used as a return value, only as a parameter
 5             void Show(T t);
 6         }
 7         /// 
 8 // the generic class inherits a generic interface that supports inversion
 9         /// 
10         public class CustomerListIn:ICustomerListIn
11         {
12             public void Show(T t)
13             {
14                 Console.WriteLine(t);
15             }
16         }
Inverter in----------------------------------------------------*/
2             {
3 // inversion: let the right side use the parent class. After modifying the inversion with in, t can only be used as a parameter, not as a return value
4                 ICustomerListIn listIn1 = new CustomerListIn();
5                 ICustomerListIn listIn2 = new CustomerListIn();
6                 listIn1.Show(new Cat());
7             }

5. Covariant, inverse together

1 / * --- covariant out inverter in together----------------------------------------------------*/
 2         public interface ITogetherList
 3         {
 4             void Show(inT t);
 5             outT Get();
 6             outT Do(inT t);
 7         }
 8         public class TogertherList : ITogetherList
 9         {
10             public void Show(Y1 y)
11             {
12                 Console.WriteLine("This is {0}", y.GetType().Name);
13             }
14             public Y2 Get()
15             {
16                 Console.WriteLine(typeof(Y2).Name);
17                 return default(Y2);
18             }
19             public Y2 Do(Y1 y)
20             {
21                 Console.WriteLine("This is {0}", y.GetType().Name);
22                 Console.WriteLine(typeof(Y2).Name);
23                 return default(Y2);
24             }
25         }
/*--------------------------------------------------Examples of covariant out inverter in together----------------------------------------------------*/
            {
                ITogetherList list1= new TogertherList();
                Itogeterlist List2 = new togerterlist(); // covariant: when the parent class is on the left, covariant can be replaced by a subclass
                Itogetherlist list3 = new togertherlist(); // contravariant: when the left side is a subclass, covariant can be replaced by a parent class
                Itogetherlist list4 = new togertherist(); // covariant + inverse
            }

Summary:                             

1 // the so-called covariant inversion is only for generics
2 // can only be placed before the generic parameters of an interface or delegate
3 /// public delegate TResult Func(T arg);

10、 Generic cache [to put it bluntly, it is to save the data and use it next time. The common practice is to create an internal static dictionary, because the dictionary is not easy to lose and can hold many items]

1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 using System.Threading.Tasks;
 7 
 8 namespace LearnGenericFirst1
 9 {
10     /// 
11 // generic caching
12 // caching is an essential part of large-scale website architecture. It is the first step to improve performance
13 // cache: to put it bluntly, it is to save the data and use it directly next time. The common practice is to create an internal static dictionary, because the dictionary is not easy to lose and can hold many items
14     /// 
15     public class GenericCacheTest
16     {
17         public static void show()
18         {
19             for (int i = 0; i < 5; i++)
20             {
21                 Console.WriteLine(GenericCache.GetCache());
22                 Thread.Sleep(10);
23                 Console.WriteLine(GenericCache.GetCache());
24                 Thread.Sleep(10);
25                 Console.WriteLine(GenericCache.GetCache());
26                 Thread.Sleep(10);
27                 Console.WriteLine(GenericCache.GetCache());
28                 Thread.Sleep(10);
29                 Console.WriteLine(GenericCache.GetCache());
30                 Thread.Sleep(10);
31             }
32         }
33          
34         /// 
35 // / previous cache [dictionary cache], static attributes are resident in memory
36         /// 
37         /// 
38         /// 
39         public class DictionaryCache
40         {
41             private static Dictionary _TypeTimeDictionary = null;
42             /// 
43 // our CLR guarantees that it will be executed the first time it is enabled, and only once
44             /// 
45             static DictionaryCache()
46             {
forty-seven Console.WriteLine ("this is dictionarycache static constructor! "";
48                 _TypeTimeDictionary = new Dictionary();
49             }
50             public static string GetCache()
51             {
52                 Type type = typeof(Type);
53 // first, judge whether there is any in the dictionary. If there is, take it directly from the dictionary. If not, calculate it and put the data in
54                 if (!_TypeTimeDictionary.ContainsKey(type))
55                 {
56                     _TypeTimeDictionary[type] = string.Format("{0}_{1}", typeof(T).FullName, DateTime.Now.ToString("yyyyMMddHHmmss.fff"));
57                 }
58                 return _TypeTimeDictionary[type];
59             }
60 
61         }
62 
63         /// 
64 // the CLR generates a different copy for each different T of genericcache
65 // / it is suitable for different types of scenarios where a piece of data needs to be cached, which is efficient
66 // static objects are stored in memory and are unique and will not be recycled. However, if static objects are placed in generic types, everything will change. The compiler will produce different copies for different types of static objects
67 // limitation: for a type, only one value can be saved, and two values cannot be saved
68         /// 
69         /// 
70         public class GenericCache
71         {
72             static GenericCache()
73             {
seventy-four Console.WriteLine ("this is dictionarycache static constructor! "";
75                 _TypeTime = string.Format("{0}_{1}", typeof(T).FullName, DateTime.Now.ToString("yyyyMMddHHmmss.fff"));
76             }
77             private static string _TypeTime = "";
78             public static string GetCache()
79             {
80                 return _TypeTime;
81             }
82         }
83 
84     }
85 }

 

Recommended Today

JS function

1. Ordinary function Grammar: Function function name (){ Statement block } 2. Functions with parameters Grammar: Function function name (parameter list){ Statement block } 3. Function with return value Grammar: Function function name (parameter list){ Statement block; Return value; } Allow a variable to accept the return value after calling the function Var variable name […]