Why is this called overload?
It is called "overload" because it is overloaded. We “overload” a thing when we give two possible implementations for this thing, and then we must decide what to use (what is called overload resolution).
When we overload methods, we give two or more implementations of the method with the given name. When we overload operators, we provide two or more possible implementations for an operator with the given syntax. It is the same.
Make sure you do not confuse overloading with overriding. Overloading is simply the existence of two methods / statements with the same name / syntax in the same declaration space. Overriding deals with how the contents of a virtual method slot are populated at run time.
Do all objects have an implementation of all operators by default?
No.
Is public static object operator +(object o1, object o2) predefined somewhere and somehow?
No.
This would somehow mean that objects by default do not have predefined operators, so how then is the term overload?
I do not understand the question. Of course, C # has predefined operators.
I do not want to publicly publish this statement
Then do not use the operator; make a private, internal or secure method.
The design of C # is that the operator is always part of the total surface area. It is very confusing to have operators that matter, which depends on which scope of use the use is in. C # was carefully designed to be the language of the "pit of quality", where the choice of language designers forces you to refuse to write embarrassing, buggy, hard to access programs for refactoring. The requirement that user statements are public and static is one of those design subtle points.
(1) Objects do not have predefined operators by default
Of course they do it; There are hundreds of predefined operators on many objects. To add, for example, the following predefined overloads of the + operator exist:
int + int uint + uint long + long ulong + ulong double + double float + float decimal + decimal enum + underlying (for any enum type) underlying + enum int? + int? uint? + uint? long? + long? ulong? + ulong? double? + double? float? + float? decimal? + decimal? enum? + underlying? underlying? + enum? string + string object + string string + object delegate + delegate (for any delegate type)
Refer to the C # specification for a list of all the predefined overloads of all other operators.
Note that overload resolution for operators has two phases: first, overload resolution tries to find the user-defined overload that is the best; only if no suitable candidates are detected, are these predefined overloads taken into account by the resolution of the overload.
(2) The defining operators are not described as creating an operator, it is described as overload, which is somehow contradictory (to me) with point 1.
I don’t understand why you consider this inconsistent or, for that matter, what you consider inconsistent. The term "overload" is used sequentially to describe both operators and methods; in both cases, this means using the same syntax to denote two or more different things, and this ambiguity is then resolved using "overload resolution." The exact details of the method resolution algorithms and the overload algorithms are different, but they are the same in the general algorithm: first, a set of candidates is identified, then inapplicable candidates are deleted, then the survival algorithm eliminates the applicable candidates that are worse than the other, then the optimality algorithm determines the only best candidate that remains if there is one.
(3) You cannot restrict the operator access modifier, they must be publicly available, which does not make sense, given point 1. but the variety makes sense, given point 2.
I don’t understand which point (3) is connected with points (1) or (2) in general. The limitation that operators must be part of the public surface area is to prevent a confusing situation where you can add Fruit to Animal when you are inside the Apple class, but not when you are inside the Giraffe class.
Operators are declared inside a class or structure and therefore "belong" to the specified type, they do not float "belonging" to this type. So what do I overload exactly when I declare an operator in a class?
You overload the operator.
The fact that the same operator exists between ints does not mean that I overload anything, since this operator belongs to int. For me, this is the same as saying Foo.Hello() and Bar.Hello(string hello) are Hello overloads. They are not like they are declared in two different types. What is the difference with operators?
You accurately described the difference. Method overloading and overloading differ in many details.
If you want to accept the position that Foo.Hello() and Bar.Hello(string) are Hello overloads, this is not a common position, but it is logically consistent.
I got the impression that when overloaded you cannot change the access modifier.
Your impression is wrong; you cannot change access modifiers when overriding a virtual method. You confused this with overload.
(And I note that there is one scenario in which you need to change the access modifier when overriding the virtual method, can you determine what it is?)
I also got the impression that you cannot declare an operator from at least one of the operands of the type in which you declare the operator.
This is almost correct. The user operator must have an operand of type T , where T is a class or structure type, or T? if T is the type of structure.
So, how can the third class have access to this operator, and the other third class cannot, if it does not belong to the external assembly and the other does not? In this case, I do not find it confusing at all and even useful?
You incorrectly described my example, which could be more understandable. It's illegal:
public class Fruit { protected static Shape operator +(Fruit f, Animal a) { ... } }
Because it is strange:
public class Apple : Fruit { ... Shape shape = this + giraffe;
This is just one example. In general, it is strange to make the operator overload resolution dependent on the availability domain, therefore, the language developers have guaranteed that this will never happen if the user statements are public.
I just find overload confusing in the context of statements.
Many people do, including compilers. The user part of the specification specification is extremely difficult to analyze, and the Microsoft implementation is a rich source of compiler errors, many of which were my mistake.
I don’t understand why just declaring statements in a type should be described differently than describing the declaration of some other static method.
Well, different things are different; operators differ in many respects from methods, including their overload resolution algorithms.
I never liked that C # has overloaded operators. The C # function is a slightly improved version of the same function in C ++, but in both languages this function, in my opinion, entails much higher costs than the corresponding advantages for users.
Thank goodness at least C # does not completely abuse the operator << way that idiomatic C ++ does, although it certainly abuses + and - for delegates.