I really enjoy how in Java, we can declare variables "final" within methods to indicate that they will not change after initialization. In C#, you cannot do this same thing-- the only options are const (only works for primitives) and readonly (only works for fields declared outside of methods), neither of which I want.
I've discovered I can do something akin to the following to make a pseudo-final struct:
public readonly struct Final<T> {
public readonly T Value;
public Final(T val) {
Value = val;
}
public static implicit operator T(Final<T> final) => final.Value;
public static implicit operator Final<T>(T val) => new Final<T>(val);
}
Here's my issue: I want to be able to use this Final struct and treat it as if all I have is the datatype it's storing. For example, assume I have a class which stores 2D vectors called Vector2, with an x and y parameter. I would want to be able to write something like this:
Final<Vector2> rightVec = new Vector2(3.0f, 0.0f);
int yComponent = rightVec.y
However, I can't do the above. Instead, I'd have to write something like this:
Final<Vector2> rightVec = new Vector2(3.0f,0.0f);
int yComponent = rightVec.Value.y // <-- I don't want to have to write "Value"!
So this brings me to my questions. First, is there a way to do what I want? Second, is there a better method to do what I want than with structs? Third, is it even a good idea to try to do this?
There's no way in C# to prevent re-assignment of a locally declared variable inside a method, if that's what you're after.
You also ask if there's a "better" approach to what you're looking for. I think the closest you will find in C# is the
initkeyword:Properties with
initinstead ofsetcan only be changed in their constructor or when first constructed by the caller and can never change thereafter. This allows you to create astructwith initially assigned values that can't even be changed by other members. (It's similar togetwith noset, and toreadonlyfields, but both of those approaches require a parameterized constructor, soinitlets you do it a little more cleanly).