Skip to main content
The Closure class represents a Lua function (technically a closure with upvalues). It wraps bytecode and any captured variables from outer scopes.

Properties

OwnerScript
Script
Gets the script owning this function.
Script owner = closure.OwnerScript;
EntryPointByteCodeLocation
int
Gets the entry point location in bytecode. Used internally by the VM.

Call Methods

Call()
method
Calls this function with no arguments.
returns
LuaValue
The return value(s) of the function
LuaValue func = script.Globals.Get("myFunction").Function;
LuaValue result = func.Call();
Call(params object[])
method
Calls this function with the specified CLR arguments.
returns
LuaValue
The return value(s) of the function
LuaValue result = func.Call(10, "hello", true);
Call(params LuaValue[])
method
Calls this function with the specified Lua arguments.
returns
LuaValue
The return value(s) of the function
LuaValue result = func.Call(
    LuaValue.NewNumber(42),
    LuaValue.NewString("test")
);

Delegate Conversion

GetDelegate()
method
Gets a delegate wrapping calls to this scripted function.
returns
ScriptFunctionDelegate
A delegate that can be called from C#
ScriptFunctionDelegate del = func.GetDelegate();
object result = del(1, 2, 3);
GetDelegate<T>()
method
Gets a strongly-typed delegate wrapping calls to this scripted function.
returns
ScriptFunctionDelegate<T>
A delegate returning the specified type
ScriptFunctionDelegate<int> del = func.GetDelegate<int>();
int result = del(1, 2); // Automatically converted to int

Upvalue Methods

GetUpvaluesCount
method
Gets the number of upvalues (captured variables) in this closure.
returns
int
The number of upvalues
int count = closure.GetUpvaluesCount();
GetUpvalueName
method
Gets the name of the specified upvalue.
returns
string
The upvalue name
string name = closure.GetUpvalueName(0);
GetUpvalue
method
Gets the value of an upvalue. To set the value, use GetUpvalue(idx).Assign(…).
returns
LuaValue
The upvalue
LuaValue upval = closure.GetUpvalue(0);
Console.WriteLine($"Upvalue: {upval}");

// Modify the upvalue
upval.Assign(LuaValue.NewNumber(42));
GetUpvaluesType
method
Gets the type of upvalues contained in this closure.
returns
UpvaluesType
None (no upvalues), Environment (only _ENV), or Closure (real closure with multiple upvalues)
var type = closure.GetUpvaluesType();
if (type == Closure.UpvaluesType.None) {
    Console.WriteLine("Pure function, no upvalues");
}

UpvaluesType Enum

None
enum
The closure has no upvalues (technically a function, not a closure).
Environment
enum
The closure has _ENV as its only upvalue.
Closure
enum
The closure is a real closure with multiple upvalues.

Example Usage

using SolarSharp.Interpreter;
using SolarSharp.Interpreter.DataTypes;

var script = new Script();

// Define a function in Lua
script.DoString(@"
    function add(a, b)
        return a + b
    end
    
    function makeCounter()
        local count = 0
        return function()
            count = count + 1
            return count
        end
    end
");

// Get and call a simple function
Closure addFunc = script.Globals.Get("add").Function;
LuaValue result = addFunc.Call(10, 20);
Console.WriteLine(result.Number); // 30

// Use as a delegate
ScriptFunctionDelegate<double> addDel = addFunc.GetDelegate<double>();
double sum = addDel(5, 7); // 12.0

// Get a closure with upvalues
LuaValue counterFunc = script.Call(script.Globals.Get("makeCounter"));
Closure counter = counterFunc.Function;

Console.WriteLine($"Upvalues: {counter.GetUpvaluesCount()}"); // 1 (count variable)
Console.WriteLine($"Upvalue name: {counter.GetUpvalueName(0)}"); // "count"

// Call the counter multiple times
Console.WriteLine(counter.Call().Number); // 1
Console.WriteLine(counter.Call().Number); // 2
Console.WriteLine(counter.Call().Number); // 3

// Inspect and modify upvalue
LuaValue countUpvalue = counter.GetUpvalue(0);
Console.WriteLine($"Current count: {countUpvalue.Number}");
countUpvalue.Assign(LuaValue.NewNumber(100));
Console.WriteLine(counter.Call().Number); // 101

Build docs developers (and LLMs) love