Skip to content

Variables and passing arguments

SyntaxDescriptionNote
int a = 1;Local variable
var a = 1;Type inference
int a = 1, b = 2;Combined declaration
{ int a = 1; }Scope from a block
int a; a = 1;Assign after declaringReading it before assignment is a CS0165 error.
private static int Counter;Static variableThe value is separate for each instance of the Behaviour and is not shared between instances.
int Take(int v)Pass by valueAssigning to the parameter in the callee doesn’t change the caller’s variable.
int Read(in int v)in parameter
bool TryHalf(int v, out int result)out parametersWhat you may pass is a local variable or a parameter of the calling method, or a field the callee itself does not read or write. An array element cannot be passed (there is no way to tell whether the same array is also reachable under another name).
void Bump(ref int v)ref parametersThe same restriction on what may be passed applies as for out.
int.TryParse("1", out n)out from a method on the runtime
out int nDeclare an out variable inline
if (…) a = 1; else a = 2;Assignment in if and else
switch … case … default …Assignment in every switch case
_ = Make();Discard a return value
SyntaxDescriptionErrorReasonAlternative
Bump(ref a[0])Pass an array element by refTUKI0001by designTake it into a local variable first, then assign that to the element
ref int r = ref a;A local variable that refers to another variable (a ref local)TUKI0001undecidedHold a value
ref int First(int[] xs)Return the variable itselfTUKI0001undecidedReturn a value and write it back at the call site
r = ref b;Replace what it points toTUKI0001undecidedSame as above
ref (c ? ref a : ref b)Choose what it points to by a conditionTUKI0001undecidedSame as above
Make(out _);Discard the out destinationTUKI0001, TUKI0099not yetReceive it with a variable
int.TryParse("1", out _)Discard the out of a method on the runtimeTUKI0099not yetReceive it with a variable
Forms that hold a variable’s location as a valueNone of them are supported. ref locals, ref returns, ref reassignment, and ref in a conditional expression are all TUKI0001 (return the modified result and assign it at the call site).
Definite assignmentC#‘s rules apply as-is. Assigning in every branch lets you read it afterwards, but reading before assignment is CS0165
using UnityEngine;
using Tsukimi;
public class VarLocal : TsukimiBehaviour
{
void Start()
{
int a = 1;
Debug.Log(a); // => 1
}
}
using UnityEngine;
using Tsukimi;
public class VarInferredType : TsukimiBehaviour
{
void Start()
{
var a = 1;
Debug.Log(a); // => 1
}
}
using UnityEngine;
using Tsukimi;
public class VarMultipleDeclarators : TsukimiBehaviour
{
void Start()
{
int a = 1, b = 2;
Debug.Log(a + b); // => 3
}
}
using UnityEngine;
using Tsukimi;
public class VarBlockScope : TsukimiBehaviour
{
void Start()
{
{
int a = 1;
Debug.Log(a); // => 1
}
}
}

It can be declared first and assigned later.

using UnityEngine;
using Tsukimi;
public class VarAssignBeforeUse : TsukimiBehaviour
{
void Start()
{
int a;
a = 1;
Debug.Log(a); // => 1
}
}

It belongs to the type rather than to an instance.

using UnityEngine;
using Tsukimi;
public class VaStatic : TsukimiBehaviour
{
void Start()
{
Counter = Counter + 1;
Debug.Log(Counter); // => 1
}
private static int Counter;
}

A copy of the value is passed to the parameter.

using UnityEngine;
using Tsukimi;
public class VaValueParam : TsukimiBehaviour
{
void Start()
{
Debug.Log(Take(1)); // => 1
}
private int Take(int v) { return v; }
}

That the callee won’t assign to the parameter can be stated in the declaration.

using UnityEngine;
using Tsukimi;
public class VarInParameter : TsukimiBehaviour
{
private int Read(in int v) { return v; }
void Start()
{
int a = 1;
Debug.Log(Read(in a)); // => 1
}
}

The method you call writes the value.

using UnityEngine;
using Tsukimi;
public class VarOutParameter : TsukimiBehaviour
{
private bool TryHalf(int v, out int result)
{
result = v / 2;
return v % 2 == 0;
}
void Start()
{
int half;
bool even = TryHalf(10, out half);
Debug.Log(even); // => true
Debug.Log(half); // => 5
}
}

The method you call reads it and then changes it.

using UnityEngine;
using Tsukimi;
public class VarRefParameter : TsukimiBehaviour
{
private void Bump(ref int v)
{
v = v + 1;
}
void Start()
{
int count = 1;
Bump(ref count);
Bump(ref count);
Debug.Log(count); // => 3
}
}
using UnityEngine;
using Tsukimi;
public class VarOutFromExtern : TsukimiBehaviour
{
void Start()
{
int n;
bool ok = int.TryParse("1", out n);
Debug.Log(ok ? n : 0); // => 1
}
}
using UnityEngine;
using Tsukimi;
public class VarOutDeclaredInline : TsukimiBehaviour
{
void Start()
{
bool ok = int.TryParse("1", out int n);
Debug.Log(ok ? n : 0); // => 1
}
}
using UnityEngine;
using Tsukimi;
public class VaDefAssignIf : TsukimiBehaviour
{
void Start()
{
int a;
if (true) { a = 1; } else { a = 2; }
Debug.Log(a); // => 1
}
}
using UnityEngine;
using Tsukimi;
public class VaDefAssignSwitch : TsukimiBehaviour
{
void Start()
{
int k = 1;
int a;
switch (k) { case 1: a = 1; break; default: a = 0; break; }
Debug.Log(a); // => 1
}
}
using UnityEngine;
using Tsukimi;
public class VarDiscard : TsukimiBehaviour
{
private int calls;
void Start()
{
_ = Make();
Debug.Log(calls); // => 1
}
private int Make()
{
calls = calls + 1;
return 1;
}
}