Does C# operator overloading support "+=" like C++? [duplicate] - c#

This question already has answers here:
C# operator overload for `+=`?
(10 answers)
Closed 3 years ago.
I'm from C++ and using C# as newbie, just tried this out:
class Class1
{
int mI = 0;
string mS = "ab";
public static Class1 operator + (Class1 obj1, Class1 obj2)
{
return new Class1()
{
mI = obj1.mI + obj2.mI,
mS = obj1.mS + obj2.mS
};
}
public static void operator += (Class1 obj1)
{
mI += obj1.mI;
mS += obj1.mS;
}
}
I found that operator+= function doesn't compile, saying:
error CS1019: Overloadable unary operator expected.
So C# doesn't do this kind of operator overloading at all?

You can overload +, but not +=, as per the documentation:
Assignment operators cannot be explicitly overloaded. However, when you overload a binary operator, the corresponding assignment operator, if any, is also implicitly overloaded. For example, += is evaluated using +, which can be overloaded.
So, as you can read, += is considered x = x + y. That's why it is not allowed to overload the += operator.

Related

Why Operator Methods Should Be Static In C#? [duplicate]

This question already has answers here:
Why must C# operator overloads be static?
(3 answers)
Closed 3 years ago.
Why in C# we use static with operator methods?
I have tried reading different articles on internet but they didn't help me in answering it.
public static int operator+(int I, Complex C)
{
return C.x + I;
}
Also when i try to do c+2 it works fine but when i do 2+c it gives me an error because i am not having an extra overloaded function for this call match of parameters. Is there any way by which i can run both statements like c+2 and 2+c with a single overloaded operator definition of function?
The specification has the following to say about user-defined operators (emphasis mine)
The following rules apply to all operator declarations:
•An operator declaration shall include both a public and a static modifier.
•The parameter(s) of an operator shall have no modifiers.
•The signature of an operator (§15.10.2, §15.10.3, §15.10.4) shall differ from the signatures of all other operators declared in the same class.
•All types referenced in an operator declaration shall be at least as accessible as the operator itself (§8.5.5).
•It is an error for the same modifier to appear multiple times in an operator declaration.
"Because the spec says so" might not be the most satisfying answer, but it's the best I have. I'm guessing that virtual dispatch doesn't make much sense for operators.
As for your second question, my approach would be to implement a private static method that does your operation, and then have two operator implementations point to it.
Something like this:
public static int operator+(int i, Complex c) => AddInt(c, i);
public static int operator+(Complex c, int i) => AddInt(c, i);
private static int AddInt(Complex c, int i) => c.X + i;

Calling functions in C# ternary operator [duplicate]

This question already has answers here:
C# Conditional Operator Not a Statement?
(9 answers)
Closed 6 years ago.
Why is this code not valid? Pretty sure it's legit in C /C++
Pseudocode:
String s = Console.ReadLine();
int x = 0;
Int32.TryParse(s, out x) ? Console.WriteLine("Foo") : Console.WriteLine("bar");
The ternary operator is used to return values and those values must be assigned.
If you want to invoke void methods in a ternary operator, you can use delegates like this:
String s = Console.ReadLine();
int x = 0;
(Int32.TryParse(s, out x) ? new Action(() => Console.WriteLine("Foo")) : () => Console.WriteLine("bar"))();
console.writeline return void.. The conditional operator (?:) returns one of two values depending on the value of a Boolean expression
MSDN
As discussed here, in C#, not every expression can be used as a statement.

Does += operator ensures an EXPLICIT conversion or implicit CASTING in C#?

The example below compiles:
public static void Main()
{
Byte b = 255;
b += 100;
}
but this one below fails
public static void Main()
{
Byte b = 255;
b = b + 100;
}
with
Error 1 Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)
Does this mean that for C# += operator provides EXPLICIT conversion?
Eric Lippert answered your question at great length.
Another interesting aspect of the predefined compound operators is
that if necessary, a cast – an allegedly “explicit” conversion – is
inserted implicitly on your behalf. If you say
short s = 123;
s += 10;
then that is not analyzed as s = s + 10 because short plus int is int,
so the assignment is bad. This is actually analyzed as
s = (short)(s + 10);
so that if the result overflows a short, it is automatically cut back
down to size for you.
See also part two.

defining operator + , = and +=

I once read the following statement from a C++ notes,
In C++, defining operator + and = does not give the right meaning to +=. This language-design bug is fixed in C#
I would like to know what exactly does this statement want to say? Is that related to operator overload?
I prefer C++ operator overloading mechanism. It definitely not a design bug according to me.
+, = and += are three different operators. If you want to use += you need to overload +=. Overloading + and = won't make += work.
I would like to add that in E1 += E2 E1 gets evaluated only once as far as C++ is concerned. I don't know the exact rules in C#.
It says, that in C# if you have overloaded operator + C# automatically will emulate operator += as combination of + and = (a=a+b is equal to a+=b). In C++ it's not implemented, but it's not a bug. In C++ + and = doesn't give you += because mostly += works faster than +, because there is no need to create one more object.
That's why mostly operator + is writen using += operator. Consider fallowing code:
class foo
{
public:
foo& operator+=(const foo& rhs)
{
//.......
}
};
const foo operator+(const foo& lhs,const foo& rhs)
{
foo temp = lhs;
return temp+= rhs;
}
It means that in C++ if you defined your own operator + and operator = for your class, that still does not mean that your class will automatically support the += operator. If you want the += operator to work for your class, you have to define the += explicitly and separately.
In C#, if I understood it correctly, defining operators + and = for your class will also mean that you'll be able to use operator += with your class. The += will be "emulated" through combination of operator + and operator =. E.g. expression a += b will be interpreted as a = a + b.
It doesn't work that way in C++. If you don't define the += explicitly, a += b will result in compiler error, even if you have + and = defined.
C# does not allow operator overloading = since it does not allow direct pointer management. Its behavior is fixed based on whether it is reference or value type. For the same reason you cannot overload += . It's meaning will always be doing the sum and assignment. You can only therefore decide what the meaning for + is to your datastructure.

In overloading why the return type of the function is not considered? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Function overloading by return type?
Hi,
In overloading we say that the parameter list has to be different either by number or by type, but doesn't matter on the return type, Why is that so???
The function
//Function 1
int Add(int a, int b)
{return a+b;}
//Function 2
Double Add(Double a, Double b)
{return a+b;}
//Function 3
Double Add(int a, int b)
{return (Double)a+b;}
The functions 1 2 are overloaded, where as functions 1 and 3 are not ??? Reasons ???
Any help is really appreciated.
The compiler needs to know at compile time which function you are trying to call. If they differ only by return type, this is usually not possible. Consider, for example:
var result = Add(1, 2);
or
Console.WriteLine(Add(1, 2));
the compiler would not be able to know whether you want to execute function 1 or 3. And even if you did
double x = Add(1, 2);
the compiler would not know if you (a) want to call function 3 or (b) call function 1 and do an implicit widening conversion from int to double.
There are to many cases where that kind of overloading would not work. Here is two of them:
You don't care about the result of the method, and call it like this:
Add(3, 4);
Should this call method 1 or 3?
You use varto assign the result
var result = Add(3, 4);
This kind of overloading would be ambiguous at best, so therefore it's not allowed.
The other answers deal with why, but an aside: in C# you can simulate return-type based overloading by using (abusing?) implicit conversion operators (and deferring the operation):
using System;
class Program {
static void Main() {
int i = Add(3, 5); // prints: int overload called
double d = Add(3, 5); // prints: double overload called
}
static SuperMagicAdder Add(int a, int b)
{ return new SuperMagicAdder(a, b); }
}
struct SuperMagicAdder {
private readonly int a,b;
public SuperMagicAdder(int a, int b) { this.a = a; this.b = b; }
public override string ToString() { return a + "+" + b; }
public static implicit operator int (SuperMagicAdder value) {
Console.WriteLine("int overload called");
return value.a + value.b;
}
public static implicit operator double (SuperMagicAdder value) {
Console.WriteLine("double overload called");
return (double)value.a + value.b;
}
}
Note that interestingly, Anonymous Function Literals in C# are overloaded on their result type and it doesn't seem to pose any problems.
In C#, a lambda can be two very different things:
a piece of executable code (a subclass of Delegate actually)
an abstract representation of an operation (basically, an abstract syntax tree)
This is distinguished purely by the result type of the lambda literal:
Func<int, int> l = (i) => i + i * i;
is a piece of executable code. I can say
Console.WriteLine(l(3));
and I will get 12.
Expression<Func<int, int>> e = (i) => i + i * i;
is an abstract representation of that operation. I can say
Console.WriteLine(e);
and I will get
i => (i + (i * i))
Note that this is not just the original text. It really is an rendering of the abstract representation. The extra parentheses around the expression and inside it are there, because ToString() did an actual tree traversal of the AST and rendered it. The AST looks roughly like this:
And this
var v = (i) => i + i * i;
is simply illegal, because lambdas are overloaded on their result type, but the var keyword says "use the result type to figure out the type of v".
Allowing return types to be part of the signature would create major ambiguities in overload resolution.
For example, consider:
Add(2,3);
We are "throwing away" the value returned by the method, but which overload should be invoked?
It doesn't work well with implicit-typing, or with assigning the value to a variable that is compatible with either return-type. E.g.:
var sum = Add(2,3);
object sum = Add(2,3);

Categories

Resources