I think your professor might be referring to plain variable reassignment upon method completion (i.e. i = DoSomething(i)
), or possibly operators which result in variable reassignment under the covers, i.e. ++
.
To illustrate this:
class Immutable
{
public readonly int Value;
public Immutable(int value)
{
this.Value = value;
}
public static Immutable operator ++(Immutable obj)
{
return new Immutable(obj.Value + 1);
}
}
Now we can do the following:
Immutable a = new Immutable(1);
Immutable originalA = a;
Debug.Assert(a.Value == 1);
Debug.Assert(a == originalA); // Same instance (obviously).
a++;
Debug.Assert(a.Value == 2);
Debug.Assert(a != originalA); // New instance.
This appears to satisfy all criteria:
- You can perform LHS assignment on a variable of type
Immutable
.
- The operator method receives a copy of the original variable (you can reassign
obj
inside the body of the method, it won't affect the original location).
a
is reassigned once the operator has finished executing, and will point to the newly-created instance.
EDIT
While this is definitely not the answer as it does not satisfy any of the points, I think it's worth mentioning that you can also get the "by ref" semantics by passing around pointers, which I am sure everyone knows. What some may not know, however, is that this can also be done using TypedReference
, which is a special beast in MS C#:
void DodgyIncrement()
{
int i = 0;
this.Increment(__makeref(i));
Debug.Assert(i == 1);
}
void Increment(TypedReference i)
{
__refvalue(i, int) += 1;
}