Except J #, all supported by Microsoft. currently, the NET development language supports Operator overloading. Therefore, the same feature of simplified writing for C # has become one. an important language feature worth studying in NET development. Some people think that Operator Overloading is actually a simple way to simulate basic types of operations. But I think we need to think more about it. Why do we always want to simulate basic operations? This is because the operator overload can blur the operation and automatically speculate on the subject of the static process.
First, the operation is suffixed. A function call is actually a prefix operation. A function (representing an operation) is always written before a parameter (representing an operand. In this way, the sequence of running operations is actually the opposite to that of writing:
H (x, y)
G (H (x, y), z)
F (G (H (x, y), z), w)
The sequence running is H-> G-> F, but it must be written in turn. The binary parameter is farther and farther away from the function name. We thought in the order of computer execution, but we had to write it in turn, which was somewhat unpleasant.Member FunctionsAndExtension MethodWrite the operand (object) before:
X. H (y)
X. H (y). G (z)
X. H (y). G (z). F (w)
In this way, the order of writing is coming. This is a good solution, but today, when there is no extension method, some tasks cannot be done by the member functions. For example, in my VBF, I want Functor <T, bool> to perform logical operations such as And Or, while Functor <T, int> can only perform arithmetic operations, functor <T, string> can only be connected, and the rules are different ...... However, member functions do not have the ability to select different overloading based on type parameters, that is, the. NET generic type cannot be used.SpecialOperation. In. NET, there are only two mechanisms for determining the type during the compilation period: function overload Based on the parameter type and user-defined implicit conversion (equivalent to overload Based on the return type ). We can use the Functor <,> type static method to implement different overloading based on different type parameters. However, static methods should not only write full-type names, but also prefix operations, which make people uncomfortable to use. In this case, we will find that Operator Overloading is what we dream.
Type. op_Operator (x, y) 'static Method
X op y' Operator
The above two are equivalent. We can see that the operator overload not only can be inferred from the x and y types, but also the caller Type of the static method, you can also convert an operation to an infix-which is more suitable for binary operations than a suffix. So perfect, can we write it like this?
Class Functor (Of T, U)
Public Shared Operator And (_
X As Functor (Of T, Boolean), y As Functor (Of T, Boolean ))_
As Functor (Of T, Boolean)
End Operator
End Class
Unfortunately, this will cause compilation errors. When an operator is overloaded, its parameters must at least be of the type that defines the operator. In the compiler's opinion, it must be Functor (Of T, U), and both types Of parameters must be defined by the generic class. When I complained about this, I accidentally saw the rule for recognizing operators in the C # compiler source code (see Rotor), which does not have these restrictions, there are only two rules-the method must be static and the method with a specific name; the method must have the specialname attribute. Then we can completely cheat the compiler and use the Operator keyword provided by it to declare the Operator overload process. Instead, we use our own method of writing a specific name and specialname to create the Operator overload process:
Imports System. Runtime. CompilerServices
Class Functor (Of T, U)
<SpecialName ()> _
Public Shared Function op_BitwiseAnd (_
X As Functor (Of T, Boolean), y As Functor (Of T, Boolean ))_
As Functor (Of T, Boolean)
End Function
End Class
System. Runtime. CompilerServices. SpecialNameAttribute is a special attribute that instructs the compiler to add specialname to Declaration members. Both C # and VB compilers support this attribute. Op_BitwiseAnd is the name of the Operation operator process recognized by VB, C #, and other languages. After writing this code, compile it into a class library and reference it as a DLL. Then you will see that the compiler recognizes it as an operator overload process. When you use And for a type such as Functor <T, int>, the compiler will tell you that this operator is not supported, only for Functor <T, bool>.
Before we end, we can also see which compiler manual restrictions can be broken through:
The Protected and Private operators can be reloaded (although this is almost meaningless)
The comparison operators (=, >,>=, <=, <,<>) can be reloaded in pairs)
We can make the second operand of the shift operator not int (> and <look nice, but with this restriction, we cannot use it to do other things. Now it's better)
You can reload operators supported only by VB in C #, or load operators supported only by C # In VB (of course, they must be in the other language)
Allows you to customize Explicit conversions to support more magical writing between generic parameters.
Using this method, it seems that operators such as operator + (int, int) can be reloaded, but they cannot take effect.
Every feature of the. NET language compiler can have deep-seated purposes hidden under its surface. After the study, shanjia often finds functions that are not previously recognized. Of course, I do not recommend that you use Operator overloading. It is just a kind of thinking and a new kind of inspiration.