


First look at the comparison between basic value types in the CLR, first look at the code:
int age1 = 30; int age2 = 30; Console.WriteLine("int == int: {0}", age1 == age2); Console.WriteLine("int == int: {0}", age2 == age1); Console.WriteLine("int Equals int: {0}", age1.Equals(age2)); Console.WriteLine("int Equals int: {0}", age2.Equals(age1)); Console.WriteLine("int ReferenceEquals int: {0}", object.ReferenceEquals(age1, age2)); Console.WriteLine("int ReferenceEquals int: {0}", object.ReferenceEquals(age2, age1)); Console.ReadLine();
Running results:
For the same basic value type (both int in the above example code), == and Equals() The comparison results are the same; since ReferenceEquals() determines whether the references of two objects are equal, for value types, because a boxing operation must be performed before each judgment, that is, a temporary object is generated each time, so it will never Return false. Next, I change the type of age2 in the code to byte type. What will happen to the comparison results? Please look at the running results:
Now we find that the results of age1.Equals(age2) and age2.Equals(age1) are different. In the comparison of basic value types, == compares the content of "value". If the "value" of two objects is the same, then the two objects are "=="; but Equals() does a little more. One point, there is actually an "implicit conversion" process in Equal(), which means that age1.Equals(age2) in the above code is equivalent to int.Equals(int), and byte data can be implicitly converted to Int type data, so the result of age1.Equals(age2) is true; and age2.Equals(age1) is equivalent to byte.Equals(byte), but int type data cannot be implicitly converted to byte type because there is a possibility of loss of data precision. . In fact, the Equals() of age2.Equals(age1) should be similar to the following code:
public override bool Equals(object obj) { if (!(obj is Byte)) { return false; } return m_value == ((Byte)obj).m_value; }
If it is an explicit conversion, the result of age2.Equals((byte)age1) will be true at this time.
Let’s talk about the comparison between string types. String is a special reference type because it is "immutable". Let’s look at the code first:
string name1 = "Jack"; string name2 = "Jack"; object o1 = name1; object o2 = name2; Console.WriteLine("name1 == name2: {0}", name1 == name2); Console.WriteLine("name1 Equals name2: {0}", name1.Equals(name2)); Console.WriteLine("o1 == o2: {0}", o1 == o2); Console.WriteLine("o1 Equals o2: {0}", o1.Equals(o2)); Console.WriteLine("o1 == name2: {0}", o1 == name2); Console.WriteLine("o1 Equals name2: {0}", o1.Equals(name2)); Console.WriteLine("name1 ReferenceEquals name2: {0}", object.ReferenceEquals(name1, name2)); Console.WriteLine("o1 ReferenceEquals o2: {0}", object.ReferenceEquals(o1, o2)); Console.ReadLine();
The results of the above code execution:
The comparison results are all true, now we will explain them one by one. Some people will say that name1 and name2 both store "Jack", so name1 and name2 are actually the same object, so the comparison results of name1==name2 and name1.Equals(name2) are the same; maybe you are right. When we view the source code of string through the .NET Reflector tool, we will see this piece of code:
operator == actually returns Equals(). So for the explanation of why the comparison results of name1==name2 and name1.Equals(name2) are the same, I think this explanation is more intuitive than "name1 and name2 are actually the same object".
We know that due to the particularity of the string type, the CLR can share multiple identical string contents through a string object, so the above name1 and name2 point to the same place, and the following o1 == o2, o1 == The comparison results of name2 and object.ReferenceEquals(name1, name2) are all true, which also verifies this statement (in fact, object.ReferenceEquals(name1, o2) is also true). However, what if the assignment of name1 and name2 becomes like this?
string name1 = new string(new char[] { 'J', 'a', 'c', 'k' }); string name2 = new string(new char[] { 'J', 'a', 'c', 'k' });
Look at the running results:
The comparison results of name1==name2 and name1.Equals(name2) are as easy to understand. As mentioned above, operator== actually returns Equals() (for For reference types, Equals() compares the contents stored on the managed heap), so the results are the same. But when comparing object objects o1 and o2, the results of o1 == o2 and o1.Equals(o2) are different. == of object objects compares type object pointers. o1 and o2 are two objects, and their type object pointers must be different; Equals() compares the contents of o1 and o2 stored on the managed heap, so o1.Equals (o2) is true. This also shows that the following o1 == name2 is false and o1.Equals(name2) is true.
Let’s take a look at the internal code of object.ReferenceEquals first:
Now it should be easy to understand that the results of object.ReferenceEquals(name1, name2) and object.ReferenceEquals(o1, o2) are both false. In fact, they are two == problem of object!
Finally, let’s talk about the comparison of custom reference types.
class MyName { private string _id; public string Id { get { return _id; } set { _id = value; } } public MyName(string id) { this.Id = id; } }
Change the above declarations of name1 and name2 to:
MyName name1 = new MyName("12"); MyName name2 = new MyName("12");
Others remain unchanged, and the running result is:
name1 and name2 are two completely different objects. It should be easy to understand that the comparison results are all false.
For more related articles on understanding the differences between ==, Equals() and ReferenceEquals() in C# at once, please pay attention to the PHP Chinese website!

The char array stores character sequences in C language and is declared as char array_name[size]. The access element is passed through the subscript operator, and the element ends with the null terminator '\0', which represents the end point of the string. The C language provides a variety of string manipulation functions, such as strlen(), strcpy(), strcat() and strcmp().

The usage methods of symbols in C language cover arithmetic, assignment, conditions, logic, bit operators, etc. Arithmetic operators are used for basic mathematical operations, assignment operators are used for assignment and addition, subtraction, multiplication and division assignment, condition operators are used for different operations according to conditions, logical operators are used for logical operations, bit operators are used for bit-level operations, and special constants are used to represent null pointers, end-of-file markers, and non-numeric values.

In C, the char type is used in strings: 1. Store a single character; 2. Use an array to represent a string and end with a null terminator; 3. Operate through a string operation function; 4. Read or output a string from the keyboard.

In C language, special characters are processed through escape sequences, such as: \n represents line breaks. \t means tab character. Use escape sequences or character constants to represent special characters, such as char c = '\n'. Note that the backslash needs to be escaped twice. Different platforms and compilers may have different escape sequences, please consult the documentation.

In C language, char type conversion can be directly converted to another type by: casting: using casting characters. Automatic type conversion: When one type of data can accommodate another type of value, the compiler automatically converts it.

A strategy to avoid errors caused by default in C switch statements: use enums instead of constants, limiting the value of the case statement to a valid member of the enum. Use fallthrough in the last case statement to let the program continue to execute the following code. For switch statements without fallthrough, always add a default statement for error handling or provide default behavior.

The difference between multithreading and asynchronous is that multithreading executes multiple threads at the same time, while asynchronously performs operations without blocking the current thread. Multithreading is used for compute-intensive tasks, while asynchronously is used for user interaction. The advantage of multi-threading is to improve computing performance, while the advantage of asynchronous is to not block UI threads. Choosing multithreading or asynchronous depends on the nature of the task: Computation-intensive tasks use multithreading, tasks that interact with external resources and need to keep UI responsiveness use asynchronous.

There is no built-in sum function in C language, so it needs to be written by yourself. Sum can be achieved by traversing the array and accumulating elements: Loop version: Sum is calculated using for loop and array length. Pointer version: Use pointers to point to array elements, and efficient summing is achieved through self-increment pointers. Dynamically allocate array version: Dynamically allocate arrays and manage memory yourself, ensuring that allocated memory is freed to prevent memory leaks.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.
