C # getting started with zero infrastructure 08: code specifications,

Source: Internet
Author: User

C # getting started with zero infrastructure 08: code specifications,

I. Preface

No rules. This is especially true in the world of code. As a programmer, we don't want our code to be laughed at after it is written: Look, even a line feed is not so professional. As the development director, we do not want our team members to write code in various styles. They are colorful and ugly. To write standardized code, you must first train the code. Secondly, you can also use certain methods or tools to assist you. This section describes how to standardize our code from these two aspects. Of course, as we have learned a limited amount of coding knowledge, this section will only design the most basic and commonly used encoding specifications, but even so, after learning this section, we will make our code look more professional.

Note: I do not like to finish all the knowledge points at a time. For example, the standard may only involve part 80% today. I like this "20% principle", that is, we only spend 80% of the time to complete 20% of things, but if we want to complete the remaining things, in turn, an additional 80% of the time is required, which is a little less cost-effective. This "Principle" is important for training or learning knowledge. For our training, if we want to explain 100% of the knowledge points, it will be boring first (because some of our knowledge requires us to have the best spirit to understand ), second, it will take a lot of time (do we not want to spend the least time learning the most knowledge ?), Finally, we have never been trained to become a real expert. Therefore, our training will teach you the rest of this 80% million RMB, in this case, we hope that the habits that have been developed for you in 80% will be mined by yourself. Okay, today we have a lot of nonsense and get down to the truth. Although we haven't written many lines of code with our course, even so, I believe that it is time for you to standardize the code. So far, we have also made several restructures. The refactoring process is actually a step-by-step code-oriented process. Of course, some standards may be mastered after learning this section. For more in-depth standards, we need to gradually master them in the future, it is also interesting to note that there may also be conflicting norms... Okay, no matter what it is, it's just a taste. Let's get started later. Now, GO ......

Ii. Naming rules

1: consider using the plural number in the namespace

If a group of similar types are grouped into the same namespace, you can consider using the plural number for the namespace.

The most typical example is that in FCL, We need to store all non-generic collection classes together, so we have the System. Collections namespace. The benefit of such a naming convention is that even if we have never used a Collection class, we will know that such a namespace is a combination of a Collection (that is, Collection) related types. Do not name System. AllCollections, System. TheCollection, which either looks too tedious or ambiguous.

For example, if a series of Processor types exist in our project, you can use the namespace Processors.

2: type names are grouped by nouns and nouns.

What is the type? The pioneers in the Object-Oriented field will tell us that types correspond to actual objects in the real world. An object is a noun in linguistics. Therefore, the type should also be named by a noun or a group of nouns.

Type defines attributes and behaviors. It contains behaviors, but not the behavior itself. Therefore, the following naming rules are good for the type:

 

OrderProcessor;

ScoreManager ;

CourseRepository;

UserControl;

DomainService;

Accordingly, the following type names are considered as bad examples:

 

OrderProcess

ScoreManage

CourseSave

ControlInit

DomainProvide

The name of a verb class is more like an action in the type, rather than the type itself.

3: use adjectives to group interfaces

The interface specification is "Can do", that is to say, it regulates what types Can have. Therefore, the interface name should be an adjective group, such:

IDisposable, indicating that the type can be released;

IEnumerable, which indicates that the type contains Items and can be iterated.

It is precisely because the interface represents a type of behavior that we can make the type inherit multiple interfaces in terms of semantics, such:

 

Class SampleClass: IDisposable, IEnumerable <SampleClass>
{
// Omitted
# Region implement IDisposable

Public void Dispose ()
{
Throw new NotImplementedException ();
}

# Endregion

# Region implements IEnumerable
Public IEnumerator <SampleClass> GetEnumerator ()
{
Throw new NotImplementedException ();
}

System. Collections. IEnumerator System. Collections. IEnumerable. GetEnumerator ()
{
Throw new NotImplementedException ();
}
# Endregion
}

The above code is written to conform to both syntax and semantics. If we name the interface IDisposal, the misunderstanding is that this type is a class, not an interface. Although we add prefix I, however, I still feel that this is semantic.

However, FCL also has some exceptions that violate this rule, such as the IEnumerator interface. However, this situation is relatively rare. In most cases, we need to always consider using adjectives to name interfaces.

4: The enumerated type is named in the plural, and the enumerated element is named in the singular.

The enumeration type should have a plural form, which expresses the semantics of a group of related elements. For example:

 

enum Week
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

Here, Week has a plural meaning for the day of the Week. If we change Week to Day here, the code called will become as follows:

Day. Monday

It is not simpler and clearer than the following code:

Week. Moday

5: Use PascalCasing to name a public element

Attributes, fields, and methods open to callers should all adopt the PascalCasing naming method, for example:

 

class Person
{
    public string FirstName;
    public string LastName;

    public string Name
    {
        get
        {
            return string.Format("{0} {1}", FirstName, LastName);
        }
    }

    public string GetName()
    {
        return Name;
    }
}

In this way, the caller's code looks as follows:

Person. Name

If we do not pay attention to such naming rules, let the caller's Code look like this:

Person. name

We will first doubt the type of name, and then doubt its accessibility.

6. Use camelCasing to name private fields and local variables

Private fields and local variables are only responsible for this type. They are also named differently from open attributes and fields. CamelCasing is suitable for this type of naming.

The difference between camelCasing and PascalCasing is that the first letter is lowercase. Two naming rules are used to facilitate developers to quickly distinguish them.

In recommendation 123, we provide a naming example for public elements. The following example shows an example of private fields and local variables:

 

class Person
{
    private string firstName;
    private string lastName;

    public string Name
    {
        get
        {
            return string.Format("{0} {1}", firstName, lastName);
        }
    }

    private int doSomething(int a, int b)
    {
        int iTemp = 10;
        return a + b + iTemp;
    }
}

In this example, we can see that all the private fields, including method parameters and local variables, all follow the camelCasing rule with lowercase letters. Once we get rid of this rule, it is easy to confuse ourselves during the encoding process. What is firstName? Isn't it a private field, but a public attribute? This is too messy and terrible, because as a developer, we have to go back to the variable name to know its access scope.

7: use affirmative phrases to name Boolean attributes

A boolean value Is nothing more than True or False. Therefore, it should be expressed with a positive phrase, for example, prefix with Is, Can, and Has.

An example of a correct Boolean attribute name is as follows:

 

class SampleClass
{
    public bool IsEnabled { get; set; }

    public bool IsTabStop { get; set; }

    public bool AllowDrop { get; set; }

    public bool IsActive { get; }

    public bool? IsChecked { get; set; }
}

These names are all from. NET's latest WPF subset. Although AllowDrop is not prefixed with affirmative phrases, it expresses the meaning of whether or not as an action, therefore, it is also a recommendation name for recommended Boolean attributes.

The negative textbook of Boolean attribute naming is as follows:

 

class SampleClass
{
    public bool Checked { get; set; }
    public bool Loaded { get; set; }
}

Although affirmative adjectives or phrases express a positive meaning, these words or phrases are currently used to name events or delegate variables, so they should not be used for Boolean properties.

 

Iii. Code cleanliness

1: always provide meaningful names

Unless otherwise, do not provide meaningless names for your code.

Are you afraid that long names are required to provide sufficient meaning? Don't be afraid. In fact, we are more concerned about an iTemp when reading the code.

The int I naming method should only appear in a loop (such as a for loop). In addition, we cannot find any reason for such meaningless naming in other parts of the Code.

2: The method abstraction level should be at the same level

The method abstraction level should be at the same level. Let's look at the following code:

 

Class SampleClass
{
Public void Init ()
{
// Local initialization code 1
// Local initialization Code 2
RemoteInit ();

}

Void RemoteInit ()
{
// Remote initialization code 1
// Remote initialization Code 2
}
}

The Init method is intended to complete initialization, and initialization includes local initialization and Remote initialization. In this Code, the internal code structure of the Init method is that the local initialization code runs directly inside the method, while the Remote initialization code is encapsulated as a method and called here. This is obviously not appropriate, because local initialization and Remote initialization are equivalent. As a method, if the Remote initialization code exists as a method, the local initialization code should also exist as a method.

Therefore, the code above should be restructured:

 

Class SampleClass
{
Public void Init ()
{
LocalInit ();
RemoteInit ();
}

Void LocalInit ()
{
// Local initialization code 1
// Local initialization Code 2
}

Void RemoteInit ()
{
// Remote initialization code 1
// Remote initialization Code 2
}
}

The code after reconstruction looks clear and clear, and the Abstraction Level of all methods is at a level. As a reader, we can see at a glance what functions the Init method has accomplished.

3: One method only does one thing.

The single responsibility principle (SRP) requires only one responsibility for each type. By extending this concept to methods, we become: A method only does one thing.

What kind of code is called "doing the same thing "? Refer to the Code in the previous suggestion. The LocalInit method and the RemoteInit method are two things, but at the same abstraction level, at the type level, you can merge it into an "initialization" event. Therefore, "One thing" depends on the status of abstraction.

The following method completes too many things. Let's look at the actual code:

 

Private uint status;

Private uint unique ID;

Private uint flags;

Public string CheckDogAndGetKey ()
{
Flags = SentinelKey. SP_STANDALONE_MODE;
Status = oSentinelKey. SFNTGetLicense (Region ID, oSentinelKeysLicense. SOFTWARE_KEY, SentinelKeysLicense. LICENSEID, flags );

If (status! = SentinelKey. SP_SUCCESS)
{
Throw new FileNotFoundException ("A valid dongle is not detected, or the driver is not correctly installed ");
}

Status = oSentinelKey. SFNTReadString (SentinelKeysLicense. SP_1ST_STRING, readStringValue, MAX_STRING_LENGTH );

If (status! = SentinelKey. SP_SUCCESS)
{
Throw new FileNotFoundException ("failed to read dongle data ");
}

Return System. Text. Encoding. ASCII. GetString (readStringValue). Substring (0, 7 );
}

In the CheckDogAndGetKey method, the method is responsible for checking whether the dongle is correctly installed and reading relevant information from the dongle. Obviously, this makes CheckDogAndGetKey have too many responsibilities. We can consider refactoring the method into the following two methods:

 

Void CheckDog ()
{
Flags = SentinelKey. SP_STANDALONE_MODE;
Status = oSentinelKey. SFNTGetLicense (Region ID, oSentinelKeysLicense. SOFTWARE_KEY, SentinelKeysLicense. LICENSEID, flags );

If (status! = SentinelKey. SP_SUCCESS)
{
Throw new FileNotFoundException ("A valid dongle is not detected, or the driver is not correctly installed ");
}

}

String GetKeyFormDog ()
{
Status = oSentinelKey. SFNTReadString (SentinelKeysLicense. SP_1ST_STRING, readStringValue, MAX_STRING_LENGTH );
If (status! = SentinelKey. SP_SUCCESS)
{
Throw new FileNotFoundException ("failed to read dongle data ");
}

Return System. Text. Encoding. ASCII. GetString (readStringValue). Substring (0, 7 );
}

After reconstruction, every method is responsible for one thing. In addition, from the naming perspective, CheckDog is responsible for detecting the dongle, while GetKeyFormDog is responsible for obtaining information.

4: Avoid too long methods and too long classes

If you do not follow the "One method only does one thing" and the type of "single responsibility principle", too long methods and classes will often be generated.

If the method is too long, it means that you can reconstruct several smaller methods at a higher level. Is there any specific indicator prompt method that is too long? Yes, it is based on the number of rows. Some people suggest a method that should not exceed 10 rows, and some suggest that it should not exceed 30 rows. Of course, there is no unique standard for this. In my opinion, if a method needs to be rolled out in Visual Studio to complete reading, it must be too long, and you must think about it again.

For the type, unless for a special reason, the type code should not exceed 300 lines. If the number of rows is too large, you need to consider restructuring.

5: only publish necessary operations

Private methods and attributes that are not required to be disclosed. If you need to publish more than 9 Methods and attributes, You Need To scroll the screen to display them in intelliisense under the default settings of Visual Studio. view the figure:

We can see that the methods that intelliisense prompts for us within the visible range also include three methods inherited from the Object, in this example, there are only 6 valuable information displayed for us. The Sample type code is as follows:

 

class SampleClass
{
    int field1;
    int field2;
    int field3;

    public int MyProperty1 { get; set; }

    public int MyProperty2 { get; set; }

    public int MyProperty3 { get; set; }

    public int MyProperty4 { get; set; }

    public int MyProperty5 { get; set; }

    public int MyProperty6 { get; set; }

    public void Mehtod1()
    {
    }

    public void Mehtod2()
    {
    }

    public void Mehtod3()
    {
    }
}

If we add more public attributes or methods for SampleClass, it means that we increase the search cost when using intelliisense.

If we plan to make a method public or internal, consider this necessity carefully. Remember, by default, Visual Studio provides the private access modifier for the type members generated by us. In my opinion, this is Microsoft's mental implication: Access is disabled unless necessary.

In addition to class members, the type should be the same. The type that should not be disclosed to other projects should be set to internal. Think about the default type access toggle is internal, which means that if the type is not intentionally set, the type should only be open to this project. Therefore, following this rule will make our API look much refreshed.

 

Iv. Static code checking tools

In addition to the specifications we need to learn, there are also some static check tools in the world to help us analyze whether our code meets certain standards. At present, we use StyleCop to help us complete static checks of code specifications.

What is StyleCop?

StyleCop was Microsoft's internal static code and forced formatting tool in its early years. Although some of Microsoft's open-source projects run StyleCop, we still find many warnings (of course, we can also understand that various MS Projects define some of their own specifications ). Its official address is:

Http://archive.msdn.microsoft.com/sourceanalysis

At this moment in this section, the current version is: StyleCop-4.7.44.0. Next let's take a look at how to use StyleCop for code specification checks.

Note: The specification setting file used in the video is: http://back.zuikc.com/Settings.zip

 

V. Video

Non-public part. Please contact the most course (www.zuikc.com)

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.