C # static constructors and compare with Golang

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

ORM Framework in the base class defines the addition and deletion of the method, sub-class implementation to save as concise as possible, except for each attribute represents the table structure (that is, Poco Plain old Csharp Object) at least have the table name and other information.

Consider the code snippet:

public abstract class RecordBase<T> where T : RecordBase<T>, new(){    protected static string TableName;    public static List<T> GetByID(int id)    {        using (var conn = OpenConnection())        {            var sql = "select * from " + TableName + " where ID = @id";            return conn.Query<T>(sql, new {id = id}).First();        }    }}public class User : RecordBase<User>{    public int Id { get; set; }    public string Name { get; set; }    static User ()    {        TableName = "Users";    }}

The calling code is similar to the following:

var u = User.GetByID(1);

The TableName is assigned to a static constructor in the user subclass, so the GetByID correct table name can be obtained when the method in the parent class executes.

A static constructor of a type is typically used for the initial identification of a type's static data, and it will be executed only once.

(recordbase<t> If there are multiple subclasses, the referenced tablename properties are independent of each other.) )

It looks like this scenario is a typical application of static constructors.

Unfortunately, the above code has a pit.

In MSDN, static constructors are defined statically constructor as follows:

A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only. It is called automatically before the first instance is created or any static members are referenced.

GetByIDThe method is defined in the parent class, and RecordBase<T> even if the call is written, it is actually referred to as a User.GetByID() static member of the parent class, not a subclass, and if the program has not previously created any child class instances, the static constructor of the subclass may still not be executed here.

That is, if the other part of the program is not referenced to the user subclass, then the User.GetByID() exception is thrown: TableName is empty.

Before calling GetByID, you must first create a user instance (or call the user instead of the static member of the parent class) to work correctly, for example:

var tmp = new User();var u = User.GetByID(1);

If the ORM is so realized, this is a big pit; it is also quite troublesome to write explicit code to invoke the subclasses when the program is forced to initialize.

The workaround I found is to add a static constructor for the parent class, where the static constructor of the subclass is fired.

    public abstract class RecordBase<T> where T : RecordBase<T>, new()    {        protected static string TableName;        static RecordBase()        {            System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle);        }    }

GetByIDis a static member of the parent class that is called, the static constructor of the parent class is called first by the runtime, and the static constructor of the subclass can be called through compilerservices by the type of the subclass that has the subtype in the function.

(The static constructor of a type is only run once if the Runclassconstructor function is called multiple times.) )

Although the static constructors in C # can control the initialization of various types accurately, they are called only when needed, and not repeated.

But if the control is not accurate, or the implementation of code is not sufficient attention, it may be in the program to leave a pit. If the lack of relevant experience knowledge, it will be confused when stepping on the pits do not know how to deal with.

In fact, I was involved in the development of the year, so this time to test the non-instantiation of the subclass, directly called GetByID to determine if there is a problem with this block. If I am a novice and do not understand the document well enough, the mining pits are duly completed.

C # This language is very good in many aspects, but specific to the type, module initialization this piece, as Go programmer, I would say go to do better.

The go language does not allow invalid references, and it does not allow the module to iterate, ensuring that all the Go language modules/types have a clear dependency.

The module method is automatically run before all modules are referenced init .

Go programmers need to consider the scene is simple, naturally it is not easy to mining pits.

Some languages or tools of "strong" is reflected in a wide range of functions, the more features, the more combined scene, the programmer will need to carefully figure out how to deal with the specific scenarios, which is actually a considerable mental burden, and the program is often just to do "no obvious bug."

And a language like go, where its "power" is embodied in providing a small number of features that do not overlap as much as possible, programmers can easily consider all potential scenarios and write "Obviously no bugs" programs.

In terms of the term is orthogonality, I saw the first time that the English word is not understand, check Chinese translation: Orthogonality. Words are known, but the composition of the word, still do not understand.

:)

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.