. NET-Generic parsing

Source: Internet
Author: User


"1": Introduction to Generics



Generics are an important new feature in c#2.0, and generics are a special mechanism provided by the CLR and programming languages that support another form of code reuse. Generics are typically used in conjunction with collections and methods that act on collections, and of course they can be used alone.



C # is a strongly typed language, and before generics are raised, we use the code of the collection, and each time we convert it requires an implicit cast, and we all know that the final base class for all objects is object, and every time we use object, Either transform what type you want to cast.
With generics, we don't need to convert from generics, because generics change each type directly to the type of parameter passed in based on the type of parameter passed in by the receiver.
In general, the process of creating a generic class is to start with an existing concrete class, changing each type to a type parameter one at a to achieve the best balance of generalization and usability. When you create your own generic classes, you need to pay special attention to the following things:



What types are generalized to type parameters.



In general, the more types you can parameterize, the more flexible your code becomes and the better the reusability. However, too much generalization can make it difficult for other developers to read or understand the code.



What constraints should be applied to type parameters if constraints exist



A useful rule is to apply as many constraints as possible, but still enable you to handle the types that must be handled. For example, if you know that your generic class is only for reference types, apply a class constraint. This prevents your class from being used unexpectedly for value types, and allows you to use the as operator for T and check for null values.



Whether to decompose the generic behavior into base classes and subclasses.



Because generic classes can be used as base classes, the design considerations that apply here are the same as for non-generic classes. See later in this topic for rules that inherit from a generic base class.



Whether to implement one or more generic interfaces.



For example, if you design a class that will be used to create an item in a generic-based collection, you might have to implement an interface, such as IComparable, where T is the type of your class.






"2": how generics are represented



Generics can also have interfaces and delegates for reference types and value types, and an FCL (DLL assembly, which contains the. NET Framework, a generic list is defined in a class that manages a collection of objects, and if we want to use this generic list, you can specify a specific data type when you use it.
Generics are expressed as "T", such as: List<t> t represents an unspecified data type, and we can look at the reference definition of generics in the FCL class:
The System.Collections.Generic namespace contains interfaces and classes that define generic collections, which allow users to create strongly typed collections that provide better type security and performance than non-generic strongly typed collections.
The procedure for creating a generic class is to start with an existing concrete class, changing each type to a type parameter one at a to achieve the best balance of generalization and availability






"3": Benefits of generics



1: Make the code more concise and clear



As we mentioned earlier, generics are reusable, reduce our code volume, make our programs easier to develop and maintain, for example:
Example 1: When getting a database from a database, we often return a DataTable type and convert it to a list collection. So if there is no generics, I will generally do so.


public List<TrainingUser>GetTrainingUser(string userId)

        {

            DataTable dt =

                     SqliteHelper.ExecuteDataset(System.Data.CommandType.Text,

                        @"

                        SELECT DISTINCT UserId,TrainingId FROM TRAININGUSER AS TU

                        INNER JOIN [USER] AS U

                         ON U.ID = TU.USERID 

                        JOIN [TRAINING] AS T

                        ON T.ID = TU.TRAININGID

                        WHERE U.ID = '"+userId+"' AND T.ENDTIME > DATETIME('now', 'localtime') AND T.StartTime <= DATETIME('now', 'localtime') ;").Tables[0];

            return DataTableToList(dt);

        }

  

        private List<TrainingUser> DataTableToList(DataTabledt)

        {

            List<TrainingUser> list = new List<TrainingUser>();

            if(dt. Rows.Count > 0 )

            {

                foreach (DataRow row in dt .Rows)

                {

                    TrainingUser trainingUser = new TrainingUser();

                    if(row["UserId" ] != null)

                    {

                        trainingUser .UserId = row["UserId"].ToString();

                    }

                    if(row["TrainingId" ] != null)

                    {

                        trainingUser.TrainingId = row["TrainingId"].ToString();

                    }

                    list.Add(trainingUser);

                }

            }

            return list;

        }


In method Datatabletolist, we pass in a DataTable object and then iterate through the object values of each row to assign a value to the Traininguser type object, which is just one of the methods, if our type has training/ User/project and other types, we are going to write a lot like datatabletolist such methods? This reflects the way in which the code is redundant and maintenance inconvenient, so we use generics to solve



Example 2: Using generics to make the above code clearer and more concise


public static List<T> ToList1<T>(DataTable dt) whereT : class, new()

        {

            var prlist =new List<PropertyInfo>();

            Type type = typeof(T);

            Array.ForEach(

                type.GetProperties(),

                p =>

                {

                    if(dt.Columns.IndexOf(p.Name) !=-1)

                    {

                        prlist.Add(p);

                    }

                });

            var oblist = new List<T>();

  

            // System.Data.SqlTypes.

            foreach(DataRow row in dt.Rows)

            {

                var ob = new T();

                prlist.ForEach(

                    p =>

                    {

                        if(row[p.Name] != DBNull.Value)

                        {

                            p.SetValue(ob, row[p.Name], null);

                        }

                    });

                oblist.Add(ob);

            }

  

            return oblist;

        }


In the above method, we define a generic method, which uses the principle of reflection in the internal implementation, transforms the DataTable into a list (reflecting the summary of subsequent essays, where only the generic part is concerned), we define a static return value of List<t>, As we said before, T: represents any type (except enumeration), Tolist1<t>, which means that when we call this method, we also give the method name a type value, which is consistent with its return value type (generics are type safe), Where: Conditions for limiting T, such as where t:class,new () means that T can only be a class, or a type object, so we can do this when we call


public List<TrainingUser>GetTrainingIdByUserId(string userId)

        {

              List<TrainingUser> trainingUserList =  DataTableHelper.ToList1<TrainingUser>(

                    SqliteHelper.ExecuteDataset(System.Data.CommandType.Text,

                        @"

                        SELECT DISTINCT UserId,TrainingId FROM TRAININGUSER AS TU

                        INNER JOIN [USER] AS U

                         ON U.ID = TU.USERID 

                        JOIN [TRAINING] AS T

                        ON T.ID = TU.TRAININGID

                        WHERE U.ID = '"+ userId +"' AND T.ENDTIME > DATETIME('now', 'localtime') AND T.StartTime <= DATETIME('now', 'localtime') ;").Tables[0]);

              return trainingUserList ;

        }


The datatablehelper.tolist1<traininguser> in the code is a generic method that we just wrote, so that we can see that the,tolist<t> passed in the type Traininguser, At the same time the receiver is:list<t> = list<traininguser>,
This allows us to use datatablehelper.tolist1<t> (DataTable dt) for type conversion, even if we have other types such as Training/user/project.



2: Improving the performance of the program



The performance is better compared to generics and non-generics, why? First, the type of the generic is the caller (the recipient), to directly assign the value (type-safe), then there is no type conversion problem, and secondly, generics reduce the process of boxing and unpacking.
Example 3: Performance comparison for value type generics vs. non-generics


Private static void ListTest()

        {

            List<int>list = new List<int>();

            For(inti = 0; i < 100; i++)

            {

                list.Add(i);

                Int a = list[i];

            }

            List =null;

        }

        Private static void ArrListTest()

        {

            ArrayList arr = new ArrayList();

            For(inti = 0; i <100; i++)

            {

                arr.Add(i);

                Int s = (int)arr[i];

            }

            Arr = null;

        }

  

             Stopwatch sw = new Stopwatch();

            sw.Start();

            ListTest();

            Console.WriteLine(" Execute value type method duration using generic List: "+ sw.Elapsed.ToString());

            sw.Stop();

  

            Stopwatch sw1 = new Stopwatch();

            sw1.Start();

            ArrListTest();

            Console.WriteLine(" Executes a value type method using a non-generic ArrayList duration: "+ sw1.Elapsed.ToString());

            sw1.Stop();

            Console.ReadLine(); 


By cyclic 100来 comparison, the result is:






We can see that the non-generic time is more than the time of the generic 0.0000523 seconds, the generics than the non-generic time to some more, then we will change the value of the loop 1000 times. The result is:






Generics are 0.0000405 seconds shorter than non-generic executions
Can we change the time to 100000? The result is:






This gap is 0.0054621 and as the number of executions increases, the time for generics will gradually increase in the non-generic type,
By anti-compilation We can also see:
Generic type:






Non-generic






From the compilation we can also see that in the generic method, the received Int32, non-generic is an object, followed by generics will not be boxed and unboxing operations, non-generic each execution of the boxing and unpacking operations.



3: Type safety



In Example 1, 2, 3 we have a note that the generic send must be consistent with the receiver, otherwise it will report an exception, for example:



Example 4:












Home



Latest Articles



IT Workplace



Front



Back end



Mobile side



Database



Operation and Maintenance



Other technologies



-Navigation bar-Home Latest Articles It career front end-javascript-html5-css back end-python-java-c/c++-php-. Net-ruby-go Mobile-Android-ios database Operations-Linux-unix Other technologies-git-machine learning-algorithms-testing-information security-Vim



Bole Online > Home > All articles > Development >. NET generic parsing (top)



. NET generic parsing (top)



2015/07/03 · Development .net



Share to: 6






Filming and editing "Pregnancy diary"



PS Great God Clearance Tutorial



PS Primer Basics-Magic Color grading



The front-end session of MU-class network Technology Salon









Source: Liu Bin's blog



"1": Introduction to Generics



Generics are an important new feature in c#2.0, and generics are a special mechanism provided by the CLR and programming languages that support another form of code reuse. Generics are typically used in conjunction with collections and methods that act on collections, and of course they can be used alone.



C # is a strongly typed language, and before generics are raised, we use the code of the collection, and each time we convert it requires an implicit cast, and we all know that the final base class for all objects is object, and every time we use object, Either transform what type you want to cast.
With generics, we don't need to convert from generics, because generics change each type directly to the type of parameter passed in based on the type of parameter passed in by the receiver.
In general, the process of creating a generic class is to start with an existing concrete class, changing each type to a type parameter one at a to achieve the best balance of generalization and usability. When you create your own generic classes, you need to pay special attention to the following things:



What types are generalized to type parameters.



In general, the more types you can parameterize, the more flexible your code becomes and the better the reusability. However, too much generalization can make it difficult for other developers to read or understand the code.



What constraints should be applied to type parameters if constraints exist



A useful rule is to apply as many constraints as possible, but still enable you to handle the types that must be handled. For example, if you know that your generic class is only for reference types, apply a class constraint. This prevents your class from being used unexpectedly for value types, and allows you to use the as operator for T and check for null values.



Whether to decompose the generic behavior into base classes and subclasses.



Because generic classes can be used as base classes, the design considerations that apply here are the same as for non-generic classes. See later in this topic for rules that inherit from a generic base class.



Whether to implement one or more generic interfaces.



For example, if you design a class that will be used to create an item in a generic-based collection, you might have to implement an interface, such as IComparable, where T is the type of your class.






"2": how generics are represented



Generics can also have interfaces and delegates for reference types and value types, and an FCL (DLL assembly, which contains the. NET Framework, a generic list is defined in a class that manages a collection of objects, and if we want to use this generic list, you can specify a specific data type when you use it.
Generics are expressed as "T", such as: List<t> t represents an unspecified data type, and we can look at the reference definition of generics in the FCL class:
The System.Collections.Generic namespace contains interfaces and classes that define generic collections, which allow users to create strongly typed collections that provide better type security and performance than non-generic strongly typed collections.
The procedure for creating a generic class is to start with an existing concrete class, changing each type to a type parameter one at a to achieve the best balance of generalization and availability






"3": Benefits of generics



1: Make the code more concise and clear



As we mentioned earlier, generics are reusable, reduce our code volume, make our programs easier to develop and maintain, for example:
Example 1: When getting a database from a database, we often return a DataTable type and convert it to a list collection. So if there is no generics, I will generally do so.






C#


public List<TrainingUser>GetTrainingUser(string userId)

        {

            DataTable dt =

                     SqliteHelper.ExecuteDataset(System.Data.CommandType.Text,

                        @"

                        SELECT DISTINCT UserId,TrainingId FROM TRAININGUSER AS TU

                        INNER JOIN [USER] AS U

                         ON U.ID = TU.USERID

                        JOIN [TRAINING] AS T

                        ON T.ID = TU.TRAININGID

                        WHERE U.ID = '"+userId+"' AND T.ENDTIME > DATETIME('now', 'localtime') AND T.StartTime <= DATETIME('now', 'localtime') ;").Tables[0];

            return DataTableToList(dt);

        }

  

        private List<TrainingUser> DataTableToList(DataTabledt)

        {

            List<TrainingUser> list = new List<TrainingUser>();

            if(dt. Rows.Count > 0 )

            {

                foreach (DataRow row in dt .Rows)

                {

                    TrainingUser trainingUser = new TrainingUser();

                    if(row["UserId" ] != null)

                    {

                        trainingUser .UserId = row["UserId"].ToString();

                    }

                    if(row["TrainingId" ] != null)

                    {

                        trainingUser.TrainingId = row["TrainingId"].ToString();

                    }

                    list.Add(trainingUser);

                }

            }

            return list;

        }



Datatabletolisatabletolist such methods? This reflects the way in which the code is redundant and maintenance inconvenient, so we use generics to solve



Example 2: Using generics to make the above code clearer and more concise






C#


public static List<T> ToList1<T>(DataTable dt) whereT : class, new()

        {

            var prlist =new List<PropertyInfo>();

            Type type = typeof(T);

            Array.ForEach(

                type.GetProperties(),

                p =>

                {

                    if(dt.Columns.IndexOf(p.Name) !=-1)

                    {

                        prlist.Add(p);

                    }

                });

            var oblist = new List<T>();

  

            // System.Data.SqlTypes.

            foreach(DataRow row in dt.Rows)

            {

                var ob = new T();

                prlist.ForEach(

                    p =>

                    {

                        if(row[p.Name] != DBNull.Value)

                        {

                            p.SetValue(ob, row[p.Name], null);

                        }

                    });

                oblist.Add(ob);

            }

  

            return oblist;

        }


In the above method, we define a generic method, which uses the principle of reflection in the internal implementation, transforms the DataTable into a list (reflected in the summary of subsequent essays, where only the generic part is concerned), we define a static return value of List<t>, As we said before, T: represents any type (except enumeration), Tolist1<t>, which means that when we call this method, we also give the method name a type value, which is consistent with its return value type (generics are type safe), Where: Conditions for limiting T, such as where t:class,new () means that T can only be a class, or a type object, so we can do that when we call.






C#


public List<TrainingUser>GetTrainingIdByUserId(string userId)

        {

              List<TrainingUser> trainingUserList =  DataTableHelper.ToList1<TrainingUser>(

                    SqliteHelper.ExecuteDataset(System.Data.CommandType.Text,

                        @"

                        SELECT DISTINCT UserId,TrainingId FROM TRAININGUSER AS TU

                        INNER JOIN [USER] AS U

                         ON U.ID = TU.USERID

                        JOIN [TRAINING] AS T

                        ON T.ID = TU.TRAININGID

                        WHERE U.ID = '"+ userId +"' AND T.ENDTIME > DATETIME('now', 'localtime') AND T.StartTime <= DATETIME('now', 'localtime') ;").Tables[0]);

              return trainingUserList ;

        }


The datatablehelper.tolist1<traininguser> in the code is a generic method that we just wrote, so that we can see that the,tolist<t> passed in the type Traininguser, At the same time the receiver is:list<t> = list<traininguser>,
This allows us to use datatablehelper.tolist1<t> (DataTable dt) for type conversion, even if we have other types such as Training/user/project.



2: Improving the performance of the program



The performance is better compared to generics and non-generics, why? First, the type of the generic is the caller (the recipient), to directly assign the value (type-safe), then there is no type conversion problem, and secondly, generics reduce the process of boxing and unpacking.
Example 3: Performance comparison for value type generics vs. non-generics






C#


Private static void ListTest()

        {

            List<int>list = new List<int>();

            For(inti = 0; i < 100; i )

            {

                list.Add(i);

                Int a = list[i];

            }

            List =null;

        }

        Private static void ArrListTest()

        {

            ArrayList arr = new ArrayList();

            For(inti = 0; i <100; i )

            {

                arr.Add(i);

                Int s = (int)arr[i];

            }

            Arr = null;

        }

  

             Stopwatch sw = new Stopwatch();

            sw.Start();

            ListTest();

            Console.WriteLine(" Executes a value type method with a generic List duration: " sw.Elapsed.ToString());

            sw.Stop();

  

            Stopwatch sw1 = new Stopwatch();

            sw1.Start();

            ArrListTest();

            Console.WriteLine(" Executes a value type method using a non-generic ArrayList duration: " sw1.Elapsed.ToString());

            sw1.Stop();

            Console.ReadLine();



By cyclic 100来 comparison, the result is:






We can see that the non-generic time is more than the time of the generic 0.0000523 seconds, the generics than the non-generic time to some more, then we will change the value of the loop 1000 times. The result is:






Generics are 0.0000405 seconds shorter than non-generic executions
Can we change the time to 100000? The result is:






This gap is 0.0054621 and as the number of executions increases, the time for generics will gradually increase in the non-generic type,
By anti-compilation We can also see:
Generic type:






Non-generic









From the compilation we can also see that in the generic method, the received Int32, non-generic is an object, followed by generics will not be boxed and unboxing operations, non-generic each execution of the boxing and unpacking operations.



3: Type safety



In Example 1, 2, 3 we have a note that the generic send must be consistent with the receiver, otherwise it will report an exception, for example:



Example 4:






When applying a generic algorithm to a specific type, the compiler and CLR can understand the intent of the developer and ensure that only objects that are compatible with the specified data type can be used with the algorithm, and that attempting to use an object of an incompatible type can cause a compile-time error or throw an exception at run time








Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.