I was wondering, why can't I overload '=' in C#? Can I get a better explanation?
-
Do you have a specific case in mind you could share with us in which you want to overload the = ? – Neil N Mar 01 '09 at 06:40
-
@Neil N I for instance need to overload operator = for different type of points on left and right side. I have defined my own class MyPoint {double X, double Y} and I want overloaded operator = to be able to copy X and Y from System.Windows.Point on right side. `static public MyPoint operator = (System.Windows.Point winPt) {...}` Seems to me like a good idea. – Sold Out May 25 '17 at 08:51
-
@Peter, it sounds like you want to CLONE an object, and not do a reference copy, like the = operator does. – Neil N May 25 '17 at 21:23
12 Answers
Memory managed languages usually work with references rather than objects. When you define a class and its members you are defining the object behavior, but when you create a variable you are working with references to those objects.
Now, the operator = is applied to references, not objects. When you assign a reference to another you are actually making the receiving reference point to the same object that the other reference is.
Type var1 = new Type();
Type var2 = new Type();
var2 = var1;
In the code above, two objects are created on the heap, one referred by var1 and the other by var2. Now the last statement makes the var2 reference point to the same object that var1 is referring. After that line, the garbage collector can free the second object and there is only one object in memory. In the whole process, no operation is applied to the objects themselves.
Going back to why = cannot be overloaded, the system implementation is the only sensible thing you can do with references. You can overload operations that are applied to the objects, but not to references.

- 1,946
- 2
- 19
- 12

- 204,818
- 23
- 294
- 489
-
-
8@user492238: `operator=` is not an operation on the object, but on the reference. You can overload operators that are applied to *objects*, but you cannot redefine operators applied to *references*, and in this particular case, doing so would change the semantics of the language: a *reference* type would behave as a *value* type. – David Rodríguez - dribeas Feb 13 '12 at 17:21
-
4@DavidRodríguez-dribeas This is an oft-repeated statement, but it's a tautology - it restates the fact, but doesn't provied any reasoning. In C#, `operator=` acts exactly as if it was `static void assign(ref Type dst, in Type src) { dst = src; }`. How do we know that? You can do a machine translation of a C# source and replace all assignments (except the one in `assign` itself :) with invocations of `assign` and the program will act the same. Heck, it'll all get inlined and there's no overhead (I've tried it). It's a pity that the language doesn't expose this. – Kuba hasn't forgotten Monica Jul 30 '19 at 10:43
If you overloaded '=' you would never be able to change an object reference after it's been created. ... think about it - any call to theObjectWithOverloadedOperator=something inside the overloaded operator would result in another call to the overloaded operator... so what would the overloaded operator really be doing ? Maybe setting some other properties - or setting the value to a new object (immutability) ? Generally not what '=' implies..
You can, however, override the implicit & explicit cast operators: http://www.blackwasp.co.uk/CSharpConversionOverload.aspx

- 5,126
- 31
- 25
-
3The use of such an overloadable = operator would not be to make something with the object pointed to by the reference, but to 'know' that something was assigned to the variable. This is important in scenarios, where value type semantic is needed and/or for immediate disposal (at least). – user492238 Feb 13 '12 at 16:41
Actually, overloading operator =
would make sense if you could define classes with value semantics and allocate objects of these classes in the stack. But, in C#, you can't.

- 19,076
- 18
- 85
- 153
-
1Actually, it would make sense if you could define classes with value semantics, even if instances of such classes always had to be allocated on the heap. – supercat Jun 07 '12 at 22:13
-
1@supercat: Totally agreed. But cut me a little slack: Back then I did not know languages that did value semantics better than C++. – isekaijin May 19 '15 at 20:36
-
1I've never used any languages that do value semantics better than C++, and for .NET to support them anywhere near as well would require that it be much more complicated. Still, it would be helpful if there were a means by which a value type could specify that code outside the type itself should not be allowed to box or copy it; if such a thing existed, having `=` invoke a method in the type would then be very useful. Many things which can work with any type would be unable to work with such special types, but many kinds of mistakes could generate compile-time squawks. – supercat May 19 '15 at 21:30
-
In retrospect, I won't cut my past self any slack. If you need to overload the assignment operator, then the very meaning of equality is borked in your language. ML has had the correct answers regarding the meaning of equality for decades. It is unacceptable that, even today, language designers insist on being wrong. – isekaijin Nov 10 '20 at 05:26
-
Even if bitwise equality is sufficient to guarantee value equality, that does not imply that objects with different bit patterns shouldn't also be able to be equal. For example, if `x` holds a reference to one string object containing `"hello"` and `y` holds a reference to a different string object containing `"hello"`, it may be useful to treat them as equal even though they hold references to different objects. Being able to overload an assignment operator could be useful for some types where bitwise copying would work, but might not be the best way of copying a value. – supercat Nov 10 '20 at 09:20
-
If objects can be compared by pointer equality, then two different string objects containing `"hello"` are distinct. If not, then objects can be tested for structural equality recursively. Either way, there is no need to redefine the built-in equality testing operator, provided it works correctly. – isekaijin Nov 10 '20 at 18:30
-
The original question was about assignment, but you're talking about equality. Overloading the latter can often be useful if objects will often differ in ways that could be more quickly discovered using some tests than others. For example, if an object holds strings as well as computed hash values for them, comparing the strings and then--if they're equal--comparing the hash values might work, but leading off by comparing the hash values may be faster and not bothering to compare the contents unless the hash values match would likely be faster. – supercat Nov 10 '20 at 18:47
-
As for assignment, another point not yet mentioned is that there can sometimes be enormous value in knowing whether there has ever been more than one non-scope-limited reference to an object. If one holds the only reference to a string `"yellow"` and one wants a reference to a string `"fellow"`, the cheapest way to achieve that outcome would be to modify the first character of the existing string, but that would only work if there are no other references to the string. Having an assignment operator set a write-once "other references may exist" flag would allow one to identify and exploit... – supercat Nov 10 '20 at 18:51
-
...some cases where code holds the only reference to an "immutable" object, and modify the object in place without having to make an altered copy. – supercat Nov 10 '20 at 18:52
Because it doesn't really make sense to do so.
In C# = assigns an object reference to a variable. So it operates on variables and object references, not objects themselves. There is no point in overloading it depending on object type.
In C++ defining operator= makes sense for classes whose instances can be created e.g. on stack because the objects themselves are stored in variables, not references to them. So it makes sense to define how to perform such assignment. But even in C++, if you have set of polymorphic classes which are typically used via pointers or references, you usually explicitly forbid copying them like this by declaring operator= and copy constructor as private (or inheriting from boost::noncopyable), because of exactly the same reasons as why you don't redefine = in C#. Simply, if you have reference or pointer of class A, you don't really know whether it points to an instance of class A or class B which is a subclass of A. So do you really know how to perform = in this situation?

- 14,063
- 3
- 33
- 55
-
Ok using your terms, it would then make sense to overload the "reference assignment operator". Following Scenario: You want to get a notification for a reference in a collection being updated/changed. so collection[0] = new Value()... So some framework could update a Data Binding properly without ugly work around code. You would just write a generic Observable
: T and override that operator and you can do whatever you want. C# could even restrict you so you really must assign the value. There cant be a physical law preventing this from working – ecreif Jun 08 '15 at 16:43 -
@ecreif: I am not sure what you are really asking about, but if we are still within the reality of CLI/.NET/C# I would say 'no'. Although in general It might be an interesting question; if you could think about it some more and reword it to be a question on its own here or on programmers. – Tomek Szpakowicz Jun 11 '15 at 06:38
-
@ecreif: As for your scenario: "You want to get a notification for a reference in a collection being updated/changed." I would see it more as a feature of a collection. Implement a collection with notifications and design the rest of your code to use interfaces rather than concrete collections (e.g. IList instead List, IDictionary instead Dictionary) to be able to switch to your special collection. – Tomek Szpakowicz Jun 11 '15 at 06:45
-
@ecreif: Some food for thought: What do you mean by "overloading the _reference assignment operator_"? What would it be overloaded over? Nothing: all assignments? Assignments of references to specific type? Static type: based on compile time reference type? Or runtime type: based on actual type of the referenced object? Or maybe you want to base it on the object that owns the reference? But do you need it? Do you want it? What about cost of runtime type checking on each assignment? What about the compiler optimising assignments out? What about reasoning about program correctness? – Tomek Szpakowicz Jun 11 '15 at 06:53
-
It was a statement. In my scenario how would you implement that observer? I want to listen to changes of the content of the collection. Looking at the logical hierarchy there is no 'entity' this change belongs to. It does not belong to the collection because the collection is not touched or resized and it doesn't belong to Observable
because it is not touched either. What is touched is a reference inside the collection. To get a change notification I would like to override the reference assignment operator of Observable – ecreif Jul 20 '15 at 13:01. Should be called whenever an assignment occurs. -
It could work like this: override operator=(object reference, object newvalue) { NotifyAssign(reference);return newvalue; }. So using "MyClass a = b;" I could be notified using "MyClass.Assigned += SomeHandler;" – ecreif Jul 20 '15 at 13:08
One possible explanation is that you can't do proper reference updates if you overload assignment operator. It would literally screw up semantics because when people would be expecting references to update, your = operator may as well be doing something else entirely. Not very programmer friendly.
You can use implicit and explicit to/from conversion operators to mitigate some of the seeming shortcomings of not able to overload assignment.

- 5,438
- 2
- 27
- 32
-
ok, but that argumentation would just as well be true for overloads to Equals() or ToString() or | or ... ? – user492238 Feb 13 '12 at 16:44
-
Incidentally, vb6 did allow one to effectively override the assignment operator in some cases; one would use `Set xxx=yyy` if one wanted reference assignment. That led to some truly hideous semantics when applied to variant types. – supercat Jun 07 '12 at 22:14
I don't think there's any really particular single reason to point to. Generally, I think the idea goes like this:
If your object is a big, complicated object, doing something that isn't assignment with the
=
operator is probably misleading.If your object is a small object, you may as well make it immutable and return new copies when performing operations on it, so that the assignment operator works the way you expect out of the box (as
System.String
does.)

- 70,359
- 14
- 95
- 123
You can overload assignment in C#. Just not on an entire object, only on members of it. You declare a property with a setter:
class Complex
{
public double Real
{
get { ... }
set { /* do something with value */ }
}
// more members
}
Now when you assign to Real
, your own code runs.
The reason assignment to an object is not replaceable is because it is already defined by the language to mean something vitally important.

- 114,894
- 38
- 205
- 284
It's allowed in C++ and if not careful , it can result in a lot of confusion and bug hunting.
This article explains this in great detail.

- 8,029
- 3
- 35
- 46
-
The C++ orthodox canonical form, see Coplien and Stroustrup, which requires the assignment operator for user defined types to behave robustly like built-in types, results in clean code without bugs. – subsci Feb 08 '14 at 08:23
Being able to define special semantics for assignment operations would be useful, but only if such semantics could be applied to all situations where one storage location of a given type was copied to another. Although standard C++ implements such assignment rules, it has the luxury of requiring that all types be defined at compile time. Things get much more complicated when Reflection and and generics are added to the list.
Presently, the rules in .net specify that a storage location may be set to the default value for its type--regardless of what that type is--by zeroing out all the bytes. They further specify that any storage location can be copied to another of the same type by copying all the bytes. These rules apply to all types, including generics. Given two variables of type KeyValuePair<t1,t2>
, the system can copy one to another without having to know anything but the size and alignment requirements of that type. If it were possible for t1
, t2
, or the type of any field within either of those types, to implement a copy constructor, code which copied one struct instance to another would have to be much more complicated.
That's not to say that such an ability offer some significant benefits--it's possible that, were a new framework being designed, the benefits of custom value assignment operators and default constructors would exceed the costs. The costs of implementation, however, would be substantial in a new framework, and likely insurmountable for an existing one.

- 77,689
- 9
- 166
- 211
-
Who said anything about copies? `operator=` in C++ allows copying only a part of the state where it makes sense. Suppose you have a bounded type that clamps its values. In C++, when you assign to such a type from some numeric type, you can have the assignment do the clamping. That is impossible in C#, and a major pain; you need to use an explicit setter method. It's not possible to implement "natural" typesafe units in C# using safe code :( (well, you can, if you force the user never to do assignments!). – Kuba hasn't forgotten Monica Jul 30 '19 at 10:51
-
@KubaOber: In C++, if a templated structure type `Woozle
` contains a member of type `T` which overrides the assignment operator, then using the assignment operator on a `Woozle – supercat Jul 30 '19 at 14:53` would cause T's assignment operator to be used on the `T` contained therein. The .NET Framework, however, has no mechanism for processing structure assignments recursively. Instead, it just adds up the sizes of all the structure contents plus padding, and blindly copies that many bytes. Even if C# had allowed an assignment operator to be overwritten... -
...for some structure type `Widget`, it would not be able to override the behavior of code that copies a structure containing one, passes one to the constructor of a class that includes one, etc. Things like integer value clamping could be done with widening or narrowing conversion operators, but to support most of the purposes for which overridable assignment operators might be useful would have required that .NET separate value types into three distinct categories from the get-go: those that were simply assignable, those with virtual assignment operators, and those without... – supercat Jul 30 '19 at 14:58
-
...any assignment operators (generic type arguments of the latter form could only be used for declaring `ref` arguments, and would generally not be very useful without other interface constraints). I think such a design might have been workable if the product could withstand the extra time required to reach the marketplace, but I don't fault Microsoft for pushing a simpler design out the door. – supercat Jul 30 '19 at 15:00
This code is working for me:
public class Class1
{
...
public static implicit operator Class1(Class2 value)
{
Class1 result = new Class1();
result.property = value.prop;
return result;
}
}
Type of Overriding Assignment
There are two type to Override Assignment:
- When you feel that user may miss something, and you want force user to use 'casting' like float to integer, when you loss the floating value
int a = (int)5.4f;
- When you want user to do that without even notice that s/he changing the object type
float f = 5;
How to Override Assignment
For 1, use of explicit
keyword:
public static explicit override ToType(FromType from){
ToType to = new ToType();
to.FillFrom(from);
return to;
}
For 2, use of implicit
keyword:
public static implicit override ToType(FromType from){
ToType to = new ToType();
to.FillFrom(from);
return to;
}
Update:
Note: that this implementation can take place in either the FromType
or ToType
class, depending on your need, there's no restriction, one of your class can hold all the conversions, and the other implements no code for this.

- 1,888
- 1
- 37
- 55
Because shooting oneself in the foot is frowned upon.
On a more serious note one can only hope you meant comparison rather than assignment. The framework makes elaborate provision for interfering with equality/equivalence evaluation, look for "compar" in help or online with msdn.

- 17,965
- 12
- 82
- 134