[System.Serializable]
public class SomeClass
{
public int Someint;
public string Somestr;
}
public class Test : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
SomeClass sc1 = new SomeClass();
sc1.Someint = 2;
Function(sc1);
Debug.Log(sc1.Someint);
Function2(ref sc1);
Debug.Log(sc1.Someint);
}
public void Function(SomeClass sc)
{
sc.Someint = 4;
}
public void Function2(ref SomeClass sc)
{
sc.Someint = 4;
}
}
The result is same 4, 4
I expected 2, 4
What is wrong? Unity default class, function is used [ ref ] keyword?
You’re not quite understanding what “ref” does. Since SomeClass is a reference type, you’ll always change the object sent in. ref gives you a reference to the variable sent in, so you could make that variable point at a different object.
If SomeClass was a struct, you’d get the behaviour you’re expecting.
When something doesn’t seem to work the way you’d expect it’s easy to think “oh, Unity does it differently”. Sometimes that’s true, but not for passing-by-ref. Unity does it the normal way. c# - Why use the 'ref' keyword when passing an object? - Stack Overflow has the best explanations I could find (in a 60 second search).
A thing to know is that C# is based on Java, and Java got rid of call-by-ref for being a combination of too complicated and rarely needed. Other newer languages followed suit. C# added it back, probably because C# likes having lots of features. Even worse, Unity only uses call-by-ref with structs. C# structs are even trickier (and another thing Java doesn’t have, since you don’t actually need them).
Fun story: a few years ago the microsoft web site said that classes were passed-by-reference. That’s completely wrong. My guess is that whoever wrote it realized there was no way to explain it correctly in a way that wouldn’t leave most people even more confused.
Stucts are good. You need them. If every single vector operation in Unity involved visiting a random spot on the heap, stuff would just straight up be slower. Java’s adding in value types, exactly because they perform better in a ton of circumstances.
Pass by ref is not very hard to understand at all, and it enables you to write a ton of code in a much more consice way. If somebody doesn’t understand what it does, they don’t understand what a variable is, which means that they can’t really program.
The correct thing is that you “pass a reference”. It’s not very hard to explain. You could be pedantic about it, and say “pass the value of a reference”.
I didn’t say structs are bad – I said they were extra tricky in C#. Everyone learns reference types first and uses classes everywhere. Then much later they learn structs are a weird type of class which can’t have references, may need this obscure thing called call-by-reference, and is only used in weird places to run a tad faster, like games.
If you look at C++ descriptions of structs, they’re the simplest thing in the world. But then you go to C# and they start: OK, you know how classes work, here’s how structs are different… .
This was in the section on call by reference, on the microsoft site. It said reference variables are passed-by-reference. I had to read it several times when I first saw it. I agree it’s not difficult to explain CBR in general. But in C# everyone has been passing reference variables and safely changing the contents for a long time before they see pass-by-ref. And you rarely need to pass a reference variable by reference (what a mouthful). In Unity I’ve only seen it in raycasts. In practice, it’s hard to explain to a typical C#-user.