defining operator + , = and += - c#

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.

Related

Accesing a member directly by the class name

Im trying to create a ufloat class/struct in c#. It's more of a challenge for me, but would help me control some values in code. After trying a couple of approaches, I finally have one that seems to work:
public struct ufloat
{
public float Value
{
get{ return value; }
set
{
if(value < 0)
{
this.value = 0;
}
else
{
this.value = Math.Abs(value);
}
}
}
}
The problem is, I want it to behave like a typical basic type:
ufloat n = 5;
n += 1;
After some thinking I tried to overload the '=' operator, but it is not possible. Now I am out of ideas. This is why I ask, how can you change this:
ufloat x; x.value = 1;
to this:
ufloat x = 0; x = 1;
?
(Sorry if I am losing something really easy, but I am a self-taught "programmer" and I am pretty new to c#. I learnt c++ at first, and going from lower to higher level isn't easy for me.)
You can't overload the = operator, but you can overload the + operator, and then the += operator (which I believe you meant instead of =+) will work in a reasonably obvious way. You'd also need to add an implicit conversion from float to your struct though.
I would strongly advise not making the struct mutable though - instead, let the + operator return a new value. That will make it behave like every other primitive type, and like most other structs. I'd also rename it to USingle to follow the normal .NET naming conventions (where Single is the CLR name for float). You can't add your own C# alias for a name like float is for Single though.
I suspect your type will want:
A constructor accepting a float
Conversions to and from float (note that normally implicit conversions shouldn't throw exceptions - you may want to ignore that, but I'm not sure...)
Overloads for the arithmetic operators (+, -, * and /)
Overrides of ToString, Equals and GetHashCode
Implementation of IComparable<USingle> and IEquatable<USingle>
You should think about what you want to happen if you add two values which are "large positive floats" together - is the intention that your new type is able to support larger positive values than float can, or is it just "float but always non-negative"?
You can not overload = operator but you may write implicit casts, for example this one is for casting an int:
public class ufloat
{
public float value { get; }
public ufloat(int val) { value = Math.Abs(val); }
public static implicit operator ufloat(int input)
{
return new ufloat(input);
}
}
Now if you assign an int value to it, it will implicitly be converted to ufloat:
ufloat x = -5;

C# What does int i = +1 mean?

I was browsing around stack overflow and I encountered this question:
check for duplicate filename when copying files in C#
In this question, this little gem existed:
int i = +1
I have never seen this syntax before. So I opened up the interactive C# window in visual studio:
Microsoft (R) Roslyn C# Compiler version 1.3.4.60902
Loading context from 'CSharpInteractive.rsp'.
Type "#help" for more information.
> int i = +1;
> i
1
> +1 == 1
true
Is this similar to +=? Is this some new syntax? What is this operator? How is it different than a normal variable declaration?
That's the unary plus operator. From the documentation:
The result of a unary + operation on a numeric type is just the value of the operand.
In most sane contexts1 where you're writing code, it'll be optional (+1 is the same as 1 if we're writing literals).
It mostly exists for symmetry with the unary minus operator.
Most of the time, you'll not write code containing it, but if you're generating code it can be handy to be able to apply a unary operator either way2.
It has no relation to +=.
1Insane code could override this operator for custom types and make it more than a no-op. But I'd love to understand a use case where it makes code more understandable, which should be the main aim of most code.
2E.g. imagine you're chaining a set of operations together and for each additional element, you wish to change the sign of the overall result. This lets you just store an operator and apply it blindly when you finally decide to output a result
For for all signed numeric types the positive-sign is optional. So,
+1 == (+1) == 1
+1.0 == (+1.0) == 1.0
+1L == (+1L) == 1L
+1.0m == (+1.0m) == 1.0m
Do not confuse
int i = +1; // Assigns 1
which is the same as
int i = (+1); // Assigns 1
or simply
int i = 1; // Assigns 1
with
int i += 1; // INCREMENT!
which increments i.
In C# terms there is a binary + operator (the addition operator as in int i = 3 + 4;) and a unary + operator (the plus sign as in int i = +1;).
Think of it the way you think of
int i = -1
and it becomes obvious

How EXACTLY can += and -= operators be interpreted?

What exactly (under the hood) do the += and -= operators do?
Or are they implicit in that they are defined per type?
I've used them extensively, it's a very simple feature of the syntax, but I've never thought about the depths of how it works.
What Brought About the Question
I can concatenate a string value like so:
var myString = "hello ";
myString += "world";
All fine. But why doesn't this work with collections?
var myCol = new List<string>();
myCol += "hi";
You may say 'well you're attempting to append a different type, you can't append a string to a type that isn't string'. But the following doesn't work either:
var myCol = new List<string>();
myCol += new List<string>() { "hi" };
Ok, maybe it doesn't work with collections, but is the following not a (kind of) collection of event handlers?
myButton.Click += myButton_Click;
I'm obviously lacking an in-depth understanding of how these operators work.
Please note: I'm not trying to build the collection myCol in this way, in a real project. I'm merely curious about the workings of this operator, it's hypothetical.
The += operator is implicitly defined like this: a += b turns into a = a + b;, same with the -= operator.
(caveat: as Jeppe pointed out, if a is an expression, it is only evaluated once if you use a+=b, but twice with a=a+b)
You cannot overload the += and -= operator separately. Any type that supports the + operator also supports +=. You can add support for += and -=to your own types by overloading + and -.
There is however one exception hard coded into c#, which you have discovered:
Events have a += and -= operator, which adds and removes an event handler to the list of subscribed event handlers. Despite this, they do not support the + and - operators.
This is not something you can do for your own classes with regular operator overloading.
As the other answer say, the + operator is not defined for List<>. You can check it trying to overload it, the compiler would throw this error One of the parameters of a binary operator must be the containing type.
But as an experiment, you can define your own class inheriting List<string> and define the + operator. Something like this:
class StringList : List<string>
{
public static StringList operator +(StringList lhs, StringList rhs)
{
lhs.AddRange(rhs.ToArray<string>());
return lhs;
}
}
Then you can do this without problems:
StringList listString = new StringList() { "a", "b", "c" };
StringList listString2 = new StringList() { "d", "e", "f" };
listString += listString2;
Edit
Per #EugeneRyabtsev comment, my implementation of the + operator would lead to an unexpected behavior. So it should be more something like this:
public static StringList operator +(StringList lhs, StringList rhs)
{
StringList newList=new StringList();
newList.AddRange(lhs.ToArray<string>());
newList.AddRange(rhs.ToArray<string>());
return newList;
}
The short answer is that operators in C# have to be overloaded for a given type. This also holds for +=. string contains an overload of this operator, but List<> has not. Therefore, using the += operator for lists is not possible. For delegates, the += operator is also overloaded, which is why you can use += on event handlers.
The slightly longer answer is that you are free to overload the operator yourself. However, you have to overload it for your own types, so creating an overload for List<T> is not possible, while you in fact can do this for your own class that for instance inherits from List<T>.
Technically, you do not really overload the +=-operator, but the + operator. The += operator is then inferred by combining the + operator with an assignment. For this to work, the + operator should be overloaded in such a way that the result type matches the type of the first argument, otherwise the C#-compiler is going to throw an error message when you try to use +=.
The correct implementation is actually quite a bit more complex than one would think. First of all, it is not sufficient to say that a += b is exactly the same as a = a+b. It has the same semantics in the simplest of cases, but it is not a simple text substitution.
First, if the expression on the left is more complex than a simple variable, it is only evaluated once. So M().a += b is not the same as M().a = M().a + b, as that would be assigning the value on a completely different object than it was taken from, or would cause the method's side effects to happen twice.
If M() returns a reference type, the compound assignment operator can be thought of as var obj = M(); obj.a = obj.a+b; (but still being an expression). However, if obj was of a value type, this simplification would also not work, in case the method returned a reference (new in C# 7) or if it actually was an array element, or something returned from an indexer etc., then the operator ensures that it doesn't make more copies than needed to modify the object, and it will be applied to a correct place, with no additional side effects.
Event assignment is an entirely different beast, though. Outside the class scope, += results in calling the add accessor, and -= results in calling the remove accessor of the event. If these accessors aren't user-implemented, event assignment might result in calling Delegate.Combine and Delegate.Remove on the internal delegate object inside the class scope. That's also why you cannot simply get the event object outside the class, because it is not public. +=/-= is also not an expression in this case.
I recommend reading Compound Assignment by Eric Lippert. It describes this in much more detail.

dynamic arithmetic operators

I was wondering if there is a way to implement next example :
string tmp = "+";
int ans1 = 4 tmp 5;
tmp = "+";
int ans2 = 4 tmp 5;
Thanks
You can do this at least:
MyOpType tmp = "+";
int ans1 = 4 & tmp & 5;
tmp = "+"; // Could be any operator implemented by MyOpType
int ans2 = 4 & tmp & 5;
By creating a class called MyOpType which have implicit operator overloading from string to it self. This would also have to operator overload & to return some operator type which miss a single argument.
However, I do not recommend doing such "hacks" because it is not clear what the code does. And furthermore, I'm sure there is a better way to do what you what to do. So if you explain the context then we might find a better solution :)
I guess something like Result("+", 4, 5) would be cleaner and easier to implement. This leads me to the question: Where do you get the operator from? users? If not, a better solution can surely be found. If you want some form of "dynamic interpretation" then .Net Expressions trees could be interesting.
In exact that syntax - NO. Using some other syntax (closer to C#) - maybe
This subject called by "expression", there are many sample about it. the best one here
Good luck

How to use the symbols +=, *=,-=

These operands may be simple but the difficulty of finding explanations which are definitive and complete prompted me to ask. What are the character combinations containing an operand followed by an equal sign (such as *=, -=,+=, etc), what do they do and how are they useful (especially pertaining to non-numeric fields)?
Examples as well as definitions would be greatly appreciated.
Thanks
They are usually interpreted broadly as:
x += y === x = x + y
(etc for your choice of operator)
however; some languages allow you to have a bespoke += operator*, or may interpret it differently in some scenarios; for example, in C# events, += and -= mean "subscribe via the add accessor" and "unsubscribe via the remove accessor" respectively.
Typically they are just space savers, but there can be semantic differences in some cases.
*=where I mean: very different to just the + operator and assignment
Pretty much all the answers here state that x += y; is "equivalent" to "x = x + y;".
This is not actually true. They are not exactly equivalent for several reasons.
First, side effects are only performed once. Suppose you have
class C { public string S { get; set; } }
class D
{
private static C c = new C();
static C M()
{
Console.WriteLine("hello!");
return c;
}
}
The first line below prints "hello" once, as you would expect. The second prints it twice.
D.M().S += "abc";
D.M().S = D.M().S + "abc";
Second, the type system works differently for compound assignment than for regular assignment.
short b = 1;
short c = 2;
b += c;
b = b + c;
The third line is legal. The fourth line is not; a short plus a short is an int in C#, so b = b + c is an illegal assigning of an int to a short. In this case the compound assignment is actually equivalent to b = (short)(b + c);
If this subject interests you I encourage you to read sections 7.17.2 and 7.17.3 of the C# specification.
The great advantage is that you can say:
x += y;
Instead of the more verbose:
x = x + y;
Sometimes this is nice when working with strings, as you can use += to append text to an existing string.
x += expression is roughly the same thing as x = x + (expression). In other words, it calculates the right-hand side, then applies the + operator to the left-hand side and the result, and then assigns that result back into the left-hand side.
Personally, I'm not a huge fan of them. The /= operator I find a particular menace, as there are many Pascal-related languages that use that to indicate boolean inequality. Someone familiar with that who gets mixed up and tries to use it in C ends up with compiling code that produces some of the most bizzare bugs imagineable.
However, they do come in quite handy when the left-hand side is kind of large, so repeating it would throw out more noise than enlightenment.
These are compound assignment operators. For numeric fields, they're defined to add (+=), multiply (*=), and subtract (-=) the value on the right- from the variable on the left, and assign the result to the variable on the left.
However, C++ supports "operator overloading". Meaning, for any given object, the programmer can define what happens if you write x += 12 and x happens to be an object of type Foo rather than an int. This is commonly done for string classes, so if s1 = "All this" you can write s1 += " and more" and the result will be "All this and more".
Say you have x = 5. If you want to add 1 to x, you can do it in many ways:
x = x + 1;
x += 1;
x++;
++x;
They're all equivalent, and choosing any of those should leave x with 6.
So basically, if you want to multiply, divide, or subtract from x, just change the + operator to what you want.
Sorry, I didn't see that you mentioned non-numeric fields. In C# and in C++, you can do something called an "operator overload" to give a non-numeric object the ability to utilize these compound operators with a user-defined function and/or comparison.
For instance, strings are generally treated as objects and not as primitive data types, but if you execute String s = "hello"; s += "!";, you'll see that s will contain hello!. That's because the String object has an overloaded operator for += that applies an append with the rvalue ("!"--right of the += operator) to the lvalue ("hello"--left of the += operator).
A related question on C# operator overloading:
Simple way to overload compound assignment operator in C#?
If you want an explanation try reading http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Compound-assignment_operators like someone already suggested, basically a += b; is equivalent to a = a + b;. It's shorthand to make your code easier to write and read.
Here are some examples:
/* Print all evens from 0 through 20 */
for(i = 0; i <= 20; i += 2){
printf("%d\n", i);
}
/* Slow down at a linear pace */
/* Stop after speed is 0.1 or less */
while(speed > 0.1){
speed /= 1.2;
}
speed = 0;
Those should explain it. It applies to bitwise operations as well as arithmetic, but I can't think of any simple uses off the top of my head and I don't want to confuse you. There's the old temp-less swap trick - a ^= b ^= a ^= b; - which will swap the values of a and b without you having to create a temporary variable, but I'm not sure if you know what the bitwise XOR operation is at this point, so don't read into it yet.
With regard to non-numeric fields: what the operators do is completely arbitrary. In C/++/#, you can override what an operator does, allowing you to write something like:
MyObj += MyOtherObj;
// MyObj is now null
When overloading the operators, you can really do whatever you like.

Categories

Resources