The DataType enum represents all possible types that a LuaValue can have in SolarSharp.
Enum Values
A nil value, as in Lua. Represents the absence of a value.if (value.Type == DataType.Nil) {
Console.WriteLine("Value is nil");
}
A placeholder for no value. Used internally to distinguish between nil and truly absent values.// Void is used for missing optional parameters
if (value.Type == DataType.Void) {
// Use default value
}
A Lua boolean (true or false).LuaValue val = LuaValue.True;
if (val.Type == DataType.Boolean) {
bool b = val.Boolean;
}
A Lua number (always stored as double).LuaValue val = LuaValue.NewNumber(42.5);
if (val.Type == DataType.Number) {
double num = val.Number;
}
A Lua string.LuaValue val = LuaValue.NewString("hello");
if (val.Type == DataType.String) {
string str = val.String;
}
A Lua function (closure).LuaValue val = script.Globals.Get("myFunction");
if (val.Type == DataType.Function) {
Closure func = val.Function;
func.Call();
}
A Lua table.LuaValue val = LuaValue.NewTable(script);
if (val.Type == DataType.Table) {
Table tbl = val.Table;
tbl["key"] = "value";
}
A set of multiple values (used for multiple return values).LuaValue val = LuaValue.NewTuple(
LuaValue.NewNumber(1),
LuaValue.NewString("two")
);
if (val.Type == DataType.Tuple) {
LuaValue[] values = val.Tuple;
}
A userdata reference - a wrapped CLR object.LuaValue val = UserData.Create(myObject);
if (val.Type == DataType.UserData) {
UserData ud = val.UserData;
var obj = ud.Object;
}
A coroutine handle.LuaValue val = script.CreateCoroutine(func);
if (val.Type == DataType.Thread) {
Coroutine co = val.Coroutine;
co.Resume();
}
A callback function (C# function callable from Lua).LuaValue val = LuaValue.NewCallback((ctx, args) => {
return LuaValue.Nil;
});
if (val.Type == DataType.ClrFunction) {
CallbackFunction cb = val.Callback;
}
A request to execute a tail call (internal use).
A request to yield a coroutine (internal use).
Extension Methods
Converts the DataType to the string returned by Lua’s type() function.string typeName = DataType.Number.ToLuaTypeString();
Console.WriteLine(typeName); // "number"
// Type names:
// Nil/Void -> "nil"
// Boolean -> "boolean"
// Number -> "number"
// String -> "string"
// Function/ClrFunction -> "function"
// Table -> "table"
// UserData -> "userdata"
// Thread -> "thread"
Converts the DataType to a string suitable for error messages.The error-friendly type name
string error = DataType.Void.ToErrorTypeString();
Console.WriteLine(error); // "no value"
Determines whether this data type can have type metatables.True if the type can have metatables
bool canHaveMT = DataType.String.CanHaveTypeMetatables();
Console.WriteLine(canHaveMT); // true
Example Usage
Type Checking
using SolarSharp.Interpreter;
using SolarSharp.Interpreter.DataTypes;
var script = new Script();
LuaValue value = script.DoString("return 42");
switch (value.Type)
{
case DataType.Number:
Console.WriteLine($"Number: {value.Number}");
break;
case DataType.String:
Console.WriteLine($"String: {value.String}");
break;
case DataType.Boolean:
Console.WriteLine($"Boolean: {value.Boolean}");
break;
case DataType.Nil:
Console.WriteLine("Nil value");
break;
case DataType.Table:
Console.WriteLine($"Table with {value.Table.Length} items");
break;
default:
Console.WriteLine($"Other type: {value.Type}");
break;
}
Type Validation
public void ProcessValue(LuaValue value)
{
if (value.Type != DataType.Number && value.Type != DataType.String)
{
throw new ArgumentException(
$"Expected number or string, got {value.Type.ToLuaTypeString()}"
);
}
// Process the value
}
Type Conversion
public object ConvertToClr(LuaValue value)
{
return value.Type switch
{
DataType.Nil or DataType.Void => null,
DataType.Boolean => value.Boolean,
DataType.Number => value.Number,
DataType.String => value.String,
DataType.Table => ConvertTable(value.Table),
DataType.UserData => value.UserData.Object,
_ => throw new NotSupportedException(
$"Cannot convert {value.Type} to CLR object"
)
};
}
Generic Handler
public void HandleLuaValue(LuaValue value)
{
Console.WriteLine($"Type: {value.Type.ToLuaTypeString()}");
switch (value.Type)
{
case DataType.Number:
HandleNumber(value.Number);
break;
case DataType.String:
HandleString(value.String);
break;
case DataType.Function:
case DataType.ClrFunction:
HandleFunction(value);
break;
case DataType.Table:
HandleTable(value.Table);
break;
case DataType.UserData:
HandleUserData(value.UserData);
break;
case DataType.Thread:
HandleCoroutine(value.Coroutine);
break;
case DataType.Nil:
case DataType.Void:
// Handle nil
break;
}
}
var script = new Script();
// Check which types support metatables
foreach (DataType type in Enum.GetValues(typeof(DataType)))
{
if (type.CanHaveTypeMetatables())
{
Console.WriteLine($"{type} can have type metatables");
}
}
// Set a type metatable
if (DataType.String.CanHaveTypeMetatables())
{
var mt = new Table(script);
mt["__add"] = new CallbackFunction((ctx, args) => {
return LuaValue.NewString(
args[0].String + args[1].String
);
});
script.SetTypeMetatable(DataType.String, mt);
}
Tuple Handling
var result = script.DoString("return 1, 2, 3");
if (result.Type == DataType.Tuple)
{
Console.WriteLine("Multiple values returned:");
foreach (var val in result.Tuple)
{
Console.WriteLine($" {val.Type}: {val}");
}
}
else
{
Console.WriteLine($"Single value: {result}");
}
Type Relationships
Lua Type Hierarchy:
├─ Nil/Void (absence of value)
├─ Boolean (true/false)
├─ Number (double-precision float)
├─ String (immutable string)
├─ Function (Lua function/closure)
├─ ClrFunction (C# callback)
├─ Table (associative array)
├─ UserData (CLR object wrapper)
└─ Thread (coroutine)
Internal Types:
├─ Tuple (multiple return values)
├─ TailCallRequest (optimization)
└─ YieldRequest (coroutine control)
Type Checking Patterns
// Check if nil
if (value.IsNil()) { /* ... */ }
// Check if not nil
if (value.IsNotNil()) { /* ... */ }
// Check specific type
if (value.Type == DataType.Number) { /* ... */ }
// Check multiple types
if (value.Type == DataType.Number || value.Type == DataType.String) { /* ... */ }
// Validate and throw
value.CheckType("myFunc", DataType.Table, argNum: 1);