C + + programmers easy to make 10 C # errors

Source: Internet
Author: User
Tags case statement constructor current time garbage collection goto integer requires sort
c++| Program | programmer | Error We know that C # 's syntax is very similar to C + +, and the transition from C + + to C # is not the language itself, but the familiarity. NET's manageable environment and understanding of the. NET Framework.

Although C # and C + + in the grammatical changes are very small, almost no impact on us, but some changes are enough to make some of the careless C + + programmers always remember. In this article, we'll discuss 10 of the easiest mistakes that C + + programmers can make.

Error 1: Differences on destructors
It is almost entirely certain that for most C + + programmers, C # and C + + are the biggest differences in garbage collection. This also means that programmers no longer have to worry about memory leaks and ensure that all the useless pointers are removed. But we can no longer accurately control the process and timing of killing unwanted objects. In fact, there is no clear destructor in C #.

If you use unmanaged resources, you must explicitly release the resources after you do not use them. Implicit control over resources is provided by the Finalize method (in the C # language, which the destructor converts to the Finalize method), and when the object is destroyed, it is called by the garbage collector to reclaim the unmanaged resources that the object occupies.

The Finalize method should release only the unmanaged resources that are consumed by the destroyed object, not other managed objects. If you use only managed resources in your program, you do not need or should not write a finalize method for the class, and only the Finalize method is used in the processing of unmanaged resources. The Finalize method that calls an object directly is absolutely not allowed (unless you call finalize of the base class in the Finalize of the derived class). ), the garbage collector automatically invokes finalize.

Syntactically, destructor in C # is very similar to C + +, but in fact they are completely different. destructor in C # is just a shortcut to defining a Finalize method. Therefore, the following two snippets of code are different:

~myclass ()
{
Tasks that need to be completed
}

public override void Finalize ()
{
Tasks that need to be completed

Base. Finalize (); This should be the last step in this method.
}

The second section of code shows the Finalize method of calling the base class because the compiler does not automatically invoke the destructor of the base class, as the destructor does.

Wrong 2:finalize or Dispose?
It is clear from the above discussion that the explicit invocation of finalize is not allowed and can only be invoked by the garbage collector. If you want to free up a limited number of unmanaged resources (such as file handles, database connections, network connections, etc.) that you no longer use, you should use the IDisposable interface, which has a Dispose method that can help you accomplish this task. Dispose is the only way to release unmanaged resources without waiting for finalize to be invoked.

If you have already used the Dispose method, you should prevent the garbage collector from executing the Finalize method on the corresponding object. To do this, you call the static method gc.suppressfinalize and pass the pointer of the object to it as an argument, and the garbage collector does not call the Finalize method on the object until the memory is reclaimed. Accordingly, we can get the following code:

public void Dispose ()
{
Complete cleanup operation

Notifies the GC not to call the Finalize method again
System.GC.SuppressFinalize (this);
}

public override void Finalize ()
{
Dispose ();
Base. Finalize ();
}

For some objects, it might be more appropriate to call the Close method (for example, a file object call Close is more appropriate than dispose) by creating a Dispose method of a private property and a close method of the public property. And let close call Dispose to implement the Close method call to some objects.

Because it is not certain that the client code for the class will call Dispose, and that the timing of the finalizer is uncertain (we cannot control when the GC will run), C # provides a using statement to ensure that the Dispose method is invoked by the client code of the class as early as possible. The general approach is to define which object to use, then specify an active range for those objects with parentheses, and when the most inner bracket is encountered, the Dispose method is automatically invoked to process the object.

Using System.Drawing;

Class Tester
{
public static void Main ()
{
using (Font Thefont = new Font ("Arial", 10.0f)
{
Using the Thefont object
The}//compiler will call Dispose to handle Thefont objects

Font anotherfont = new Font ("Courier", 12.0f);

using (Anotherfont)
{
Using the Anotherfont object
The}//compiler will call Dispose to handle Anotherfont objects
}
}

In the first part of this example, the Font object is created in the using statement. When the using statement finishes, the system calls Dispose and handles the font object. In the second part of this example, the Font object is created outside the using statement, and when you decide to use it, it is placed inside the using statement, and the system calls Dispose when the using statement ends.

The using statement also prevents other surprises from occurring, and guarantees that the system will call Dispose.

There is a difference between a value-type variable and a reference variable in the error 3:c#
Like C + +, C # is also a strongly typed programming language. The data types in C # are divided into two categories: The C # language itself is inherently a data type and a user-defined data type, which is similar to C + +.

In addition, the C # language divides variables into value types and reference types. Unless it is contained in a reference type object, the value of the value type variable is kept on the stack, much like the variables in C + +. A variable of the reference type is also stored in the stack, and its value is the address of the corresponding object in the heap, very similar to the pointers in C + +. The value of a value type variable is passed directly to the method, and the reference variable is passed as an index when it is passed as a parameter to the method.

Classes and interfaces can create reference class variables, but it should be noted that the struct data type is a built-in data type of C # and is also a value-type data type.

Error 4: Note the implicit data type conversion
Boxing and unboxing are two procedures that make a value type data type used as an indexed data type. Value-type variables can be wrapped into a heap object and then wrapped back into a value-type variable. All data types in C #, including built-in data types, can be implicitly converted to an object. Wrapping a value variable generates an instance of an object and then copies the variable into the instance.

Boxing is recessive, and if a variable of a value data type is used where the indexed data type is required, the value-type variable is implicitly converted by the compiler to the variable of the indexed data type. Boxing can affect the performance of code execution and should therefore be avoided, especially when the data volume is large.

If you want to convert a packaged object back to its original value variant, you must unpack it explicitly. The solution takes two steps: First, the object instance is checked to make sure that they are wrapped by a value-type variable, and the second step copies the value from the instance to the value type variable. To ensure that the package is successful, the unpacked object must be an object that is generated by packing the value of a value variable.

Using System;

public class Unboxingtest
{
public static void Main ()
{
int i = 123;

Packaged
Object o = i;

Che Bao (must be dominant)
int j = (int) o;
Console.WriteLine ("J: {0}", j);
}
}

If the object being extracted is invalid, or an object of a different data type, a InvalidCastException exception is generated.

Error 5: Structure differs from class
The structure in C + + is similar to a class, except that, by default, the structure's access is public and its inherited permissions are public. Some C + + programmers use structs as data objects, but this is a convention rather than a necessity.

In C #, structs are just a user-defined data type and cannot be substituted for classes. Although structs also support properties, methods, fields, and operators, inheritance and destructor are not supported.

More importantly, the class is an indexed data type, and the structure is a value-type data type. Therefore, structs are more useful in expressing objects that do not require an index operation. Structs are more efficient in array operations and less efficient in the operation of collections. The collection requires an index, the structure must be packaged to be used in the operation of the collection, and the class is more efficient in a larger set operation.

Error 6: The virtual method must be explicitly overwritten
In the C # language, programmers must explicitly use the Override keyword when overwriting a virtual method. Suppose a window class is written by company A, the ListBox and RadioButton classes are written on the basis of the Windows class written by Company B and programmers in the purchase of company A, and B company programmers know little about the design of future changes including window classes.

If a programmer at Company B is going to add a sort method to the listbox:

public class Listbox:window
{
public virtual void Sort () {}
}

This will not be a problem until company a releases the new window class. If a company's programmers also add a sort method to the window class.

public class Window
{
public virtual void Sort () {}
}

In C + +, the Sort method in the Windows class becomes the underlying method of the sort method in the ListBox class, and the sort method in the ListBox class is invoked when you want to call the sort method in the Windows class. In C #, virtual functions are always considered to be the root of a virtual schedule. That is, once C # discovers a virtual method, it no longer looks for other virtual methods in the virtual chain. If the listbox is compiled again, the compiler generates a warning message:

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

To get the current member to overwrite the original method, you need to add the New keyword.

To eliminate the warning message, the programmer has to figure out what he wants to do. You can add new before the Sort method in the ListBox class to show that it does need to overwrite the virtual method in the window:

public class Listbox:window
{
Public new virtual void Sort () {}
}

This allows you to clear the warning message. If programmers do not want to overwrite the method in window, but need to rewrite the method, they must use the Override keyword to explicitly indicate its intent:

public class Listbox:window
{
public override void Sort () {}
}

ERROR 7: Initialization of class member variables
Initialization in C # differs from C + +. Suppose there is a person class with the private member variable age, which is generated by inheriting the person class and has a SALARYLEVEL member variable of private nature. In C + +, we can initialize SalaryLevel in the initialization section of the employee's constructor, as shown in the following code:

Employee::employee (int theage, int thesalarylevel):
Person (theage)//Initialize base class
SalaryLevel (thesalarylevel)//Initialize member variable
{
The code for the constructor
}

This method is illegal in C #. Although you can still initialize the underlying class, initializing a member variable like the code above causes a compilation error. In C #, we can initialize a member variable while declaring it:

Class employee:public Person
{
Definition of member variables
Private SalaryLevel = 3; Class
}

Note: You must explicitly define the access rights for each variable.

Error 8: Boolean variable and integer variable are two different things
In C #, a Boolean variable is not the same as an integer variable, so the following code is incorrect:

if (Somefuncwhichreturnsavalue ())

Somefuncwhichreturnsavalue returns zero to false, otherwise the idea of true is no longer feasible. The advantage is that the original error of confusing assignment with equality is not repeated. So the following code:

if (x = 5)

An error occurs at compile time, because x=5 only assigns 5 to X, not a Boolean value.

Some statements in the error 9:switch statement do not execute
In C #, if a switch statement performs some action, the program may not be able to execute to the next statement. Therefore, although the following code is legal in C + +, it is not legal in C #:

Switch (i)
{
Case 4:
Callfuncone ();

Case 5://error, not executed here
Callsomefunc ();
}

To achieve the purpose of the above code, you need to use a goto statement:

Switch (i)
{
Case 4:
Callfuncone ();
Goto Case 5;

Case 5:
Callsomefunc ();
}

If the case statement does not execute any code, all statements will be executed. As in the following code:

Switch (i)
{
Case 4:
Case 5://able to execute to
Case 6://able to execute to
Callsomefunc ();
}

The variable in error 10:c# requires an explicitly assigned value
In C #, all variables must be assigned before they are used. Therefore, you can define a variable without initializing it, and you must be assigned a value before passing it to a method.

This can be problematic if you simply pass a variable by index to the method, and the variable is the output variable of the method. For example, suppose you have a method that returns the hour, minute, and second of the current time, if you write code as follows:

int thehour;
int Theminute;
int thesecond;
Timeobject.gettime (ref thehour, ref theminute, ref Thesecond)

If you do not assign values to these three variables before using Thehour, Theminute, and Thesecond, a compilation error occurs:

Use the unassigned local variable ' thehour '
Use the unassigned local variable ' theminute '
Use the unassigned local variable ' thesecond '

We can solve this small problem with the compiler by initializing these variables to 0 or other values that have no effect on the return value of the method:

int thehour = 0;
int theminute = 0;
int thesecond = 0;
Timeobject.gettime (ref thehour, ref theminute, ref Thesecond)

This is a bit too much trouble, these variables are passed to the GetTime method and then changed. To address this problem, C # provides an out parameter modifier specifically for this situation, which allows a parameter to be referenced without initialization. For example, the parameters in GetTime do not have a point in themselves, they are just to express the output of the method. Before returning in a method, a value must be specified in the out parameter. Here is the modified gettime method:

public void GetTime (out int h, out int m, out int s)
{
h = Hour;
m = Minute;
s = Second;
}

The following is the calling method for the new gettime method:

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





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.