Top Ten traps in C # for C + + programmers Chinese Version (EXT) (2)

Source: Internet
Author: User
Tags bool case statement constructor goto integer variables printf sort
c++| Chinese traps six. Virtual methods must be explicitly overloaded

In C #, if a programmer decides to overload a virtual method, he or she must explicitly use the Override keyword.

Let's examine the benefits of doing so. Assuming company a wrote a window class, Company B purchased a copy of the window class of company A as the base class. The programmer of Company B derives from the idea that ..., which is clearly derived from the following terms. In fact, there is a "combination" (also referred to as "embedding" or "containment" (COM semantics), etc.) in the way that the class is used, and the latter does not have the problem described below "the ListBox class and the RadioButton class." The programmer of Company B does not know or cannot control the design of the window class, including any future modifications that company A may make to the window class.

Now assume that company B's programmer decides to add a sort method to the ListBox class:

public class Listbox:window

{

public virtual void Sort () {}

}

This is no problem-until company A's window class author publishes version 2 of the window class, the company a programmer adds a public sort method to the window class:

public class Window

{

public virtual void Sort () {}

}

In C + +, the new virtual method sort of the window class will be used as the base class method for the ListBox virtual method. When you try to call the sort of window, the sort of the listbox is actually called. Virtual methods in C # "the original written virtual function" is always considered the root of the fictitious schedule. This means that as long as C # finds a virtual method, it will no longer look further along the inheritance hierarchy, and if a new sort virtual method is introduced into the Window,listbox, the run-time behavior will not be changed. When the listbox is compiled again, the compiler issues the following warning:

"\class1.cs (54,24): Warning CS0114: ' Listbox.sort () ' hides inherited member ' Window.sort () '.

If you want to enable the current Member overload implementation, you can add the override keyword. Otherwise, add the New keyword.

If you want to remove this warning, the programmer must clearly indicate his intention. You can mark the sort method of the ListBox as new to indicate that it is not an overload of the virtual method of window:

public class Listbox:window

{

Public new virtual void Sort () {}

}

This way the compiler will not warn you again. On the other hand, if the programmer wants to overload the Windows method, simply add the override keyword explicitly.

Trap Seven: Can not initialize on the head

Initialization in C # is different from C + +. Suppose you have a class person, it has a private member variable of age; A derived class employee, which has a private member variable Salaryleverl. In C + +, you can initialize the SalaryLevel in the member initialization list section of the employee constructor:

Employee::employee (int theage, int thesalarylevel):

Person (theage)//Initialize base class

SalaryLevel (thesalarylevel)//Initialize member variable

{

Constructor body

}

In C #, this constructor is illegal. Although you can still initialize the base class like this, initializing a member variable will result in a compile-time error. You can assign an initial value to a member variable declaration:

Class employee:public Person

{

Here's the statement.

Private SalaryLevel = 3; Class

}

"The above code is wrong lc#, the correct wording is as follows:

Class Employee:person

{

private int salarylevel = 3;

}



You do not need to append a semicolon to each class declaration. Each member must have an explicit access-level declaration.

Trap 8. Cannot convert Boolean value to integer value

In C #, a Boolean value (True, false) differs from an integer value. Therefore, it cannot be written like this:

if (Somefuncwhichreturnsavalue ())//"I suppose this method does not return a Boolean value"

Nor can I expect if Somefuncwhichreturnsavalue returns a 0 it will be equal to false, otherwise true. The good news is that the old habits of misusing assignment operators instead of equality operators won't happen again. So, if you write this:

if (x = 5)

A compile-time error will be obtained because the result of x = 5 is 5, and it is not a Boolean value.

"The following is a logical error in C + + inadvertently, the compiler will not have any hint L run smoothly, but the result is not what you want:

C++:

#include "stdafx.h"

int main (int argc, char* argv[])

{

int n = 0;

if (n = 1)//Compiler Nothing said L General Recommendation Write 1 = n, in case of writing 1 = N compiler does not agree with J

{

printf ("1\n");

}

Else

{

printf ("0\n");

}

return 0;

}

The above run result is 1, this is not necessarily what you want.

C#:

Using System;

public class Rytestboolapp

{

public static void Main ()

{

int n = 0;

if (n = 1)//compiler does not agree that J cannot convert int to bool

{

Console.WriteLine ("1");

}

Else

{

Console.WriteLine ("0");

}

}

}

But if this is the case:

BOOL B = false;

if (b = true)

...

No, C + + or C # didn't recruit L.



C + + programmers generally like this kind of free writing:

if (MYREF)

if (MYINT)

But in C #, you have to write:

if (myref!= null)//or if (null!= myref)

if (MyInt!= 0)//or if (0!= MyInt)

Wait



Trap Nine. The switch statement cannot be "run through": That is, fall Through,beta2 's online documentation is the way to translate "

In C #, if there is code in the case statement, it cannot be "run through" to the next sentence. Therefore, although the following code is legal in C + +, it is not in C #:

Switch (i)

{

Case 4:

Callfuncone ();

Case 5://Error, cannot be "run through"

Callsomefunc ();

}

To achieve this, you need to explicitly use the goto statement:

Switch (i)

{

Case 4:

Callfuncone ();

Goto Case 5;

Case 5:

Callsomefunc ();

}

If the case statement does nothing (there is no code in it), it can be "run through":

Switch (i)

{

Case 4://Can be "run through"

Case 5://Can be "run through"

Case 6:

Callsomefunc ();

}

The following is a complete example of using switch, which also shows that the parameter type of the switch statement can be a string, and this example also demonstrates how to use the property.

Using System;

Class Ryswitchtest

{

Public Ryswitchtest (String AStr)

{

This. Strproperty = ASTR;

}

protected string Strfield;

public string Strproperty

{

Get

{

return this. Strfield;

}

Set

{

This. Strfield = value;

}

}

public void Switchstrproperty ()

{

Switch (this. Strproperty)

{

Case ("Ry01"):

Console.WriteLine ("Ry01");

Break

Case ("ry02"):

Console.WriteLine ("Ry02");

break;//If this line is commented out, the compiler will report that control cannot be run through another label from a case label (case "ry02":), if you really need to, you can write this: Goto ("ry03") or goto default.

Case ("ry03"):

Console.WriteLine ("Ry03");

Break

Default

Console.WriteLine ("Default");

Break

}

}

}

Class Ryswitchtestapp

{

public static void Main ()

{

Ryswitchtest rst = new Ryswitchtest ("ry02");

Rst. Switchstrproperty ();

}

}



Trap 10. C # requires an explicit assignment operation

C # requires explicit assignment operations, which means that all variables must be assigned before they can be used. Therefore, although you can declare a variable that is uninitialized, it cannot be passed to the method until it has a value.

This leads to a problem-when you simply want to use a variable as a "out" parameter passed to the method by reference. For example, suppose you have a method that returns the current hour, minute, and second. If you write this:

int thehour;

int Theminute;

int thesecond;

Timeobject.gettime (ref thehour, ref theminute, ref Thesecond)

Compilation will be an error because they were not initialized before using Thehour, Theminute, and Thesecond:

Use the unassigned local variable ' thehour '

Use the unassigned local variable ' theminute '

Use the unassigned local variable ' thesecond '

You can initialize them to 0 or something harmless to keep the annoying compiler quiet:

int thehour = 0;

int theminute = 0;

int thesecond = 0;

Timeobject.gettime (ref thehour, ref theminute, ref Thesecond)

But this is too stupid! Our intention is simply to pass these variables to the gettime by reference, changing their values in them. To solve this problem, C # provides an out parameter modifier. This modifier avoids the need to initialize the reference parameter as well. For example, the arguments provided for gettime do not provide any information to the method, they simply want to get information from the method. Therefore, the need to initialize them outside of the method is avoided by marking these three parameters as out types. But when returned from the method passed in, the out parameter must be assigned. The following is the changed gettime parameter declaration:

public void GetTime (out int h, out int m, out int s)

{

h = Hour;

m = Minute;

s = Second;

}

The following is a new way to invoke the GetTime method:

Timeobject.gettime (out of Thehour, out of Theminute, out Thesecond);

The complete example is as follows:

c#:[Example 1: Method parameters decorated with ref]

Using System;

Class Ryreftest

{

Public Ryreftest ()

{

This. Intfield = 1;

This. Strfield = "Strfield";

}

protected int Intfield;

protected string Strfield;

public void GetFields (ref int aint, ref string AStr)

{

aint = this. Intfield;

AStr = this. Strfield;

}

}

Class Ryreftestapp

{

public static void Main ()

{

Ryreftest RRT = new Ryreftest ();

int Intvar = 0;//if it is int intvar; The compiler will report a variable with an unassigned value Intvar

String Strvar = "0";//if String Strvar; The compiler will report a variable with an unassigned value Strvar

Rrt. GetFields (ref Intvar, ref Strvar);

Console.WriteLine ("Intvar = {0}, Strvar = {1}", Intvar, Strvar);

}

}



c#:[Example 2: Using out-decorated method parameters]

Using System;

Class Ryreftest

{

Public Ryreftest ()

{

This. Intfield = 1;

This. Strfield = "Strfield";

}

protected int Intfield;

protected string Strfield;

public void GetFields (out int aint, out string AStr)

{

aint = this. Intfield;

AStr = this. Strfield;

}

}

Class Ryreftestapp

{

public static void Main ()

{

Ryreftest RRT = new Ryreftest ();

int intvar;//So it can be, if written as int intvar = 0; Of course it's okay, J.

String Strvar; That's OK if you write string strvar = "0"; Yes, of course, J.

Rrt. GetFields (out of Intvar, out Strvar);

Console.WriteLine ("Intvar = {0}, Strvar = {1}", Intvar, Strvar);

}

}




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.