DEV Community

Cristian Sifuentes
Cristian Sifuentes

Posted on

The “var” Error in C# — Why “The contextual keyword ‘var’ may only appear within a local variable declaration” Happens

The “var” Error in C# — Why “The contextual keyword ‘var’ may only appear within a local variable declaration” Happens<br>

The “var” Error in C# — Why “The contextual keyword ‘var’ may only appear within a local variable declaration” Happens

If you’re working with Unity or learning C#, sooner or later you’ll see this legendary error:

The contextual keyword ‘var’ may only appear within a local variable declaration

At first glance, it feels completely cryptic.

You typed var like everyone says you should… and the compiler just yelled at you.

In this article you’ll learn:

  • What var actually is in C#
  • Why it only works in local variable declarations
  • The real difference between C# and old UnityScript / JavaScript-style syntax
  • How to fix common patterns that trigger this error
  • A clean, idiomatic C# version of the sprint/movement code

1. What var really means in C

In C#, var is a contextual keyword, not a magic dynamic type.

This works:

void Update()
{
    var speed = 10.0f;           // compiler infers: float
    var name  = "Player";        // compiler infers: string
    var pos   = transform.position; // compiler infers: UnityEngine.Vector3
}
Enter fullscreen mode Exit fullscreen mode

Why? Because:

  • You’re inside a method (Update())
  • You’re declaring a local variable
  • The variable has an initializer, so the compiler can infer its type

The compiler rewrites it to:

float speed = 10.0f;
string name = "Player";
Vector3 pos = transform.position;
Enter fullscreen mode Exit fullscreen mode

So far so good.


2. Where var is allowed (and where it isn’t)

var is allowed in:

  • Local variable declarations inside methods, constructors, property getters/setters, foreach, etc.
void Start()
{
    var rb = GetComponent<Rigidbody>();       // local variable
}

void Update()
{
    foreach (var enemy in enemies)           // foreach variable
    {
        // ...
    }

    using var scope = myLock.EnterScope();   // C# 8+ using declaration
}
Enter fullscreen mode Exit fullscreen mode

var is NOT allowed in:

  • Fields (class-level variables)
  • Method parameters
  • Return types
  • Properties, events, indexers
  • Any place where the type must be known outside the method body

Examples of illegal var usage:

public class PlayerController : MonoBehaviour
{
    // ❌ Not allowed – this is a field
    var speed = 10.0f;

    // ❌ Not allowed – return type
    public var CreateEnemy() { ... }

    // ❌ Not allowed – parameter type
    public void Move(var direction) { ... }
}
Enter fullscreen mode Exit fullscreen mode

All of these will give you some version of:

The contextual keyword ‘var’ may only appear within a local variable declaration

Because the compiler only lets var live in local variable declarations, where the type is fully inferable from the initializer and stays inside the method scope.


3. The Unity trap: mixing UnityScript and C

Many old Unity forum posts and tutorials use UnityScript (a JavaScript-like language Unity used to support) or JScript-style syntax, such as:

#pragma strict

@script RequireComponent( CharacterController )

var moveTouchPad : Joystick;
var rotateTouchPad : Joystick;
Enter fullscreen mode Exit fullscreen mode

This is not C#.

So if you try to “translate” that into C# and write something like:

var Sprint : MonoBehaviour  {

var float NaturalSpeed = 10.0f;
var float tempSpeed = 0.0f;
var float SpeedMultiplier = 1.2f;
var Vector3 moveDirection;
var float FirstPersonControl;

...
}
Enter fullscreen mode Exit fullscreen mode

You’ll get multiple errors, including our friend:

The contextual keyword ‘var’ may only appear within a local variable declaration

…because in C# you don’t write types after the variable name and you don’t use var in fields.

Correct C# field declarations

Here’s how these should actually look in C#:

public class Sprint : MonoBehaviour
{
    public float naturalSpeed    = 10.0f;
    private float tempSpeed      = 0.0f;
    public float speedMultiplier = 1.2f;
    private Vector3 moveDirection;
    private float firstPersonControl;
}
Enter fullscreen mode Exit fullscreen mode

Notes:

  • Access modifiers come before the type in C#: public float speed;
  • No var here — these are fields, not local variables
  • Types are float, Vector3, not var float or var Vector3

Use var inside methods, not at the field level.


4. Fixing the sprint / movement logic in clean C

Let’s refactor the sprint-related code into idiomatic C# and solve other common errors along the way (like Vector3 + float issues).

Common error 2: Operator '+' cannot be applied to operands of type 'UnityEngine.Vector3' and 'float'

In Unity, you can’t add a Vector3 and a float directly:

// ❌ Won’t compile
transform.Translate(moveDirection + tempSpeed * Time.deltaTime);
Enter fullscreen mode Exit fullscreen mode

Here moveDirection is a Vector3 and tempSpeed * Time.deltaTime is a float.

You need either:

  • A Vector3 multiplied by the float, or
  • Add the float to a specific component: moveDirection.x + something

A clean C# sprint controller

Here’s a more idiomatic version of a simple sprint/movement script:

using UnityEngine;

public class SprintController : MonoBehaviour
{
    [Header("Movement")]
    public float naturalSpeed    = 5.0f;
    public float sprintMultiplier = 1.5f;

    private Vector3 _moveDirection;
    private CharacterController _characterController;

    private void Awake()
    {
        _characterController = GetComponent<CharacterController>();
    }

    private void Update()
    {
        // 1. Read input
        float horizontal = Input.GetAxis("Horizontal");
        float vertical   = Input.GetAxis("Vertical");

        // 2. Base movement direction in local space
        _moveDirection = new Vector3(horizontal, 0f, vertical);

        if (_moveDirection.sqrMagnitude > 1f)
        {
            _moveDirection.Normalize();
        }

        // 3. Calculate speed
        float currentSpeed = naturalSpeed;

        if (Input.GetKey(KeyCode.LeftShift))
        {
            currentSpeed *= sprintMultiplier;
        }

        // 4. Apply speed and deltaTime
        Vector3 velocity = _moveDirection * currentSpeed;

        // 5. Move with CharacterController to handle collisions
        _characterController.Move(velocity * Time.deltaTime);
    }
}
Enter fullscreen mode Exit fullscreen mode

Where does var fit here? In local variables:

private void Update()
{
    var horizontal = Input.GetAxis("Horizontal");   // OK – local
    var vertical   = Input.GetAxis("Vertical");     // OK – local

    var input = new Vector3(horizontal, 0f, vertical);
    // ...
}
Enter fullscreen mode Exit fullscreen mode

You can use var for locals if it improves readability, but fields keep their explicit type.


5. Patterns that will always trigger this var error

Use this as a quick mental checklist. If you do this with var, you’ll get the error:

❌ Using var in a field

public class Example : MonoBehaviour
{
    var speed = 10f;        // ❌ Not allowed
}
Enter fullscreen mode Exit fullscreen mode

✅ Fix:

public class Example : MonoBehaviour
{
    public float speed = 10f;
}
Enter fullscreen mode Exit fullscreen mode

❌ Using var in a method signature

public var GetSpeed()            // ❌
{
    var speed = 10f;             // ✅ local – this is fine
    return speed;
}

public void Move(var direction)  // ❌
{
    // ...
}
Enter fullscreen mode Exit fullscreen mode

✅ Fix:

public float GetSpeed()
{
    var speed = 10f;   // OK
    return speed;
}

public void Move(Vector3 direction)
{
    // ...
}
Enter fullscreen mode Exit fullscreen mode

❌ Trying to “combine” UnityScript-style syntax with C

// ❌ This is not C#
var float NaturalSpeed = 10.0f;
var Vector3 moveDirection;
Enter fullscreen mode Exit fullscreen mode

✅ Fix:

// ✅ Proper C#
public float naturalSpeed = 10.0f;
private Vector3 moveDirection;
Enter fullscreen mode Exit fullscreen mode

6. When should you actually use var in C#?

Now that you know the rules, here’s a practical guideline:

👍 Great places to use var

  • When the type is obvious on the right-hand side:
var rb    = GetComponent<Rigidbody>();
var enemy = new Enemy();           // clear enough
var pos   = transform.position;    // Unity devs know this is Vector3
Enter fullscreen mode Exit fullscreen mode
  • When working with LINQ or long generic types:
var grouped = items
    .GroupBy(x => x.Category)
    .ToDictionary(g => g.Key, g => g.ToList());
Enter fullscreen mode Exit fullscreen mode

👎 Places to avoid var

  • Public API boundaries (method parameters/return types)
  • Fields that represent important domain concepts and benefit from being explicit:
// Prefer explicit type here
private float _moveSpeed;
private Vector3 _currentDirection;
Enter fullscreen mode Exit fullscreen mode

Use var primarily for local inference, not to hide important types.


7. Key takeaways

Let’s recap the big ideas so you never get bitten by this error again:

  1. var is only for local variables inside methods, not for fields, parameters or return types.
  2. It requires an initializer so the compiler can infer the type.
  3. UnityScript syntax (var x : float) is not C#. In modern Unity projects, you should use pure C#.
  4. For sprint/movement code:
    • Use explicit fields for configuration (float, Vector3)
    • Use var only for locals when it makes the code more readable
    • Don’t add Vector3 + float directly; multiply Vector3 by float instead
  5. When in doubt, start with explicit types, then introduce var where it’s safe and clear.

Written by: Cristian Sifuentes – C# / .NET Engineer | Unity Enthusiast | Clean Code Advocate

Have you run into other confusing C# compiler errors in your Unity projects?

Drop them in the comments — they often hide deeper language concepts that are worth mastering.

Top comments (0)