I have a class called Menu, and it contains a list of strings for options, so I could make a new function in the class like
addOption(string Option){
but I feel like it would make the code much prettier to be able to just say
myMenu += “Option”;
I figure if this was even possible it would be in the setter but I don’t know how to go about it
You just have to make a setter for the myMenu
property. Remember that +=
is not a real operator. It is just syntax sugar:
These two lines of code are exactly the same and if myMenu
is a property with a setter, it will be called for both of them:
myMenu += "Option";
// is identical to:
myMenu = myMenu + "Option";
because Menu is not a string, it would throw an error when trying to add a string to a Menu, but is there a way to get around that with myMenu set{} ?
Oh no your problem then is you need to define a custom +
operator for your Menu class. See Operator overloading - Define unary, arithmetic, equality, and comparison operators. - C# reference | Microsoft Learn
You’ll want your custom + operator to take a Menu and a string as parameters, and return a Menu.
setter is something else, but if you don’t know much about this, I don’t think you should mess around overloading operators anyway. there is nothing wrong with calling a method for this purpose. it’s actually preferable.
But messing around with things is how you learn, assuming you’re not learning bad habits that make a program run slow or inefficiently.
Thank you for the advice
I normally presuppose all questions to be asked with some degree of professionalism. Unless someone is obviously toying. Me saying you shouldn’t mess with overloading operators doesn’t prevent anyone from learning, but is merely a useful advice that’s meant to save your project and your sanity from an awkward practice.
using System.Collections.Generic;
using UnityEngine;
public class TestScript : MonoBehaviour {
private Menu menu = new Menu();
private void Start() {
menu += "New Game";
menu += "Load";
menu += "Options";
foreach (var option in menu.options)
Debug.Log(option);
}
public class Menu {
public readonly List<string> options = new List<string>();
public static Menu operator +(Menu menu, string s) {
menu.options.Add(s);
return menu;
}
}
}
As @orionsyndrome is touching on, don’t actually do this, probably? But this is how you’d do it if you wanted to do it.
Oh no Hippo is NAGGING
Honestly, I would be horrified for this pattern to be in my codebase. It seems fun and easy to use += for making code pretty, code is never meant to be pretty or even easy to use like a game is. Think in terms of time instead of how it looks in the IDE.
Consider how long it takes to add menu options? it’s ALMOST the same amount of time as += but merely looks nicer to you while hiding potential bugs.
What you should be doing is “is the code telling me what it does or hiding it?”
Also in terms of internal communication.
@OP
With a well-defined source code you are also communicating the intent to your colleagues, and more importantly, to your future self. It’ll get complicated, you’ll want to expand upon it, you’ll wonder why exactly you made this needless design that is surely hard to abandon at some point, yet proven obsolete. And in the meantime, no one can tell why you did what you did, what was the purpose, why you hid the actual behavior, and why this breaks consistency – perhaps not even you.
So it seams knowing how to use it is useful, but bad practice as it makes things confusing for your future self or others who wish to modify your code.
Thank you all for the advice, I didn’t mean to sound hostile, actually more joking, but I do apologize for my lack of professionalism
As an Unity example of a good overloaded +, consider transform.position=Vector3.up*4; (pretty standard Unity code). Vector3’s are just boring structs and can’t be added – except they overloaded + (for 2 of them) and * (for one and a single number). That makes them work the way everyone assumes they should work (and the way math says they should).
As a fun Unity example of when it’s not so great, consider transform.rotation*Quaternion.Euler(0,10,0). That’s a 10 degree rotation around your local y-axis. It works because quaternions overload the * operator to mean “do the second one starting at the first one’s local”. It’s correct math and correct game engine code, but it confuses the heck out of people. They’d rather have transform.rotation.addLocal(…) or addGlobal.
Operator overloading is for when a class slaps you in the face with “people expect to be able to use + and * on me”.