Revision Difference
From_Lua_to_CSharp#529957
<cat>Code.Misc</cat>
<title>From Lua to C#</title>
# What is this guide
This is meant to give an idea of the major differences between Lua and C#.
# Comments
```lua
-- Lua comments start with two minus signs
--[[
Lua multiline comment
example
--]]
```
```csharp
// C# comments start with two slashes, like most other languages
/*
C# multiline comment
example
*/
```
# Global Variables
```lua
-- you can define globals anywhere in Lua
globalVar = 100
```
```csharp
public class MyClass
{
// in C# globals need to be in a class
public static int GlobalVar = 100;
}
```
# Variable Types
```lua
-- variables in Lua don't have a static type and can store any data
local a = 100
a = "Hello"
a = function() print( "Hi" ) end
```
```csharp
var a = 100; // translated as "int a = 100;" because 100 is an int
a = "Hello"; // error: can't assign a string to an int
```
# Type conversion
```lua
local a = 123
local b = tostring( a ) -- "123"
local c = tonumber( b ) -- 123
```
```csharp
var a = 123;
var b = a.ToString(); // "123"
var c = int.Parse( b ); // 123, will throw an exception if 'b' isn't int-ish
var c = int.Parse(b); // 123, will throw an exception if 'b' isn't int-ish
// operator 'as' converts an object reference or returns 'null' on failure
var vehicle = new Car() as Vehicle; // downcast Car reference to Vehicle
var vehicle = vehicle as Car; // upcast Vehicle reference to Car
var car = vehicle as Car; // upcast Vehicle reference to Car
```
# Numbers
```lua
local a = 100
a = 5.5
a = -300.1
```
```csharp
// integer types are sbyte, byte, short, ushort, int, uint, long, ulong
// each hold a different range of values (byte holds 0 to 255 for example, while ushort holds 0 to 65535)⤶
// (u)nsigned integer types are unsigned and can only hold positive values. ⤶
int a = -300;
uint b = 333333;
// decimal types are float, double, decimal
double d = -500.888;
```
# Strings
```lua
local str = "Hello"
local str2 = 'Hello2'
local multilineStr = [[
Hello
Multiline
Hello
Multiline
]]
print( #str ) -- 5, string length
print(#str) -- 5, string length
local concated = "I have " .. 3 .. " apples!"
local formatted = string.format( "I have %d apples!", 3 )
```
```csharp
var str = "Hello";
var singleChar = 'a'; // single quotes are for a single character, not a string
var multilineStr = @"
Hello
Multiline
Hello
Multiline
"; // putting '@' before a string literal makes it a verbatim string literal
Console.WriteLine( str.Length ); // 5, string length
Console.WriteLine(str.Length); // 5, string length
var concated = "I have " + 3 + " apples!";
// {0} and {1} here correspond to the order of value arguments
// argument number 0 is '3' and argument number 1 is '2'
var formatted = string.Format( "I have {0} apples and {1} oranges!", 3, 2 );
var formatted = string.Format("I have {0} apples and {1} oranges!", 3, 2);
// putting '$' before a string allows interpolating values into it using '{value}'
var interpolated = $"I have {3} apples!";
```
# Collections
```lua
local stuff = {
1, 2, 3,
"Oh", "Hi", "Mark",
{ myFunc = function() end }
}
local numbers = { 1, 2, 3 }
local strings = { "Oh", "Hi", "Mark" }
local stats = {
["playerKills"] = 10,
["playerDeaths"] = 5,
```
```csharp
// arrays are declared by appending [] to any type. ⤶
// you must tell the compiler how much they can hold, in this case, 3 elements.⤶
// you cannot add or remove elements from arrays.⤶
var numbers = new int[3] { 1, 2, 3 };
var strings = new List<string> { "Oh", "Hi", "Mark" };
var functions = new Dictionary<string, Action>⤶
{
["myFunc"] = () => { }
⤶
// lists behave similarly to arrays, but can also be resized.
// this means you can add and remove elements from them.⤶
// since they are generic, you must tell the type it holds between angle brackets.
⤶
var strings = new List<string> { "Oh", "Hi", "Mark" };
⤶
// dictionaries are basically the equivalent of a table in Lua, you assign a value to a key.⤶
// a notable difference from Lua however, is that you cannot attempt to access a key that doesn't exist.⤶
// that will cause an exception.⤶
// Like lists, you can add and remove keys from the Dictionary using Add/Remove.⤶
var stats = new Dictionary<string, int>⤶
⤶
{⤶
{ "playerKills", 10 },⤶
{ "playerDeaths", 5 },⤶
};
```⤶
⤶
# Loops⤶
⤶
```lua⤶
for i = 1, 10, 2 do⤶
print( i ) -- 1, 3, 5, 7, 9⤶
end⤶
⤶
local a = 10⤶
⤶
repeat⤶
print( a ) -- 10, 8, 6, 4, 2, 0⤶
a = a - 2⤶
until a < 0⤶
⤶
local t = {⤶
a = 5,⤶
b = 10,⤶
c = 15⤶
}⤶
⤶
for k, v in pairs( t ) do⤶
print( k .. ' = ' .. v ) -- a = 5, b = 10, c = 15⤶
end⤶
// stats["playerKills"] is valid⤶
// stats["someOtherString"] will cause an exception.⤶
```
⤶
```csharp⤶
for ( var i = 1; i < 10; i += 2 )⤶
{⤶
Console.WriteLine( i.ToString() ); // 1, 3, 5, 7, 9⤶
}⤶
⤶
var a = 10;⤶
⤶
do⤶
{⤶
Console.WriteLine( a.ToString() ); // 10, 8, 6, 4, 2, 0⤶
a -= 2;⤶
} while ( a >= 0 );⤶
⤶
var t = new Dictionary<string, int>⤶
{⤶
{ "a", 5 },⤶
{ "b", 10 },⤶
{ "c", 15 },⤶
};⤶
⤶
foreach (var kv in t)⤶
{⤶
Console.WriteLine( $"{kv.Key} = {kv.Value}" ); //a = 5, b = 10, c = 15⤶
}⤶
```⤶
# Member Access
In Lua anything is accessible from anywhere as long as you have a reference.
```lua
-- myFile.lua
myTable = {
field = 100
}
```
```lua
-- otherFile.lua
print( myTable.field ) -- 100
```
In C# things can be **public**, **private**, **protected** and **internal**.
```csharp
// MyClass.cs
public class MyClass
{
public static void PublicMethod() { ... }
protected static void ProtectedMethod() { ... }
private static void PrivateMethod() { ... }
internal static void InternalMethod() { ... }⤶
}
```
```csharp
// OtherClass.cs
public class OtherClass : MyClass
{
public static void Test()
{
MyClass.PublicMethod(); // OK
MyClass.ProtectedMethod(); // we inherit from MyClass so OK
MyClass.PrivateMethod(); // error: PrivateMethod is private
MyClass.InternalMethod(); // OK, because we are in the same addon (other addons won't be able to).⤶
}
}
```
⤶
# Arrays⤶
⤶
<validate></validate>⤶
⤶
# For Loops⤶
##Lua⤶
⤶
In Lua there are two **for** types, numeric and generic.⤶
⤶
```lua⤶
-- numeric⤶
local str = ""⤶
for i=1,5 do⤶
if (i ~= 5) then⤶
str = str .. tostring(i) .. ", "⤶
else⤶
str = str .. tostring(i)⤶
end⤶
end⤶
⤶
print(str) -- outputs "1, 2, 3, 4, 5"⤶
```⤶
⤶
The generic for loop allows you to traverse all values returned by an iterator function.⤶
```lua⤶
-- generic⤶
-- ipairs() iteriates only through numbers indexes⤶
local str = ""⤶
local a = {"a", "b", "c", key = "e", key2 = "f", "d"}⤶
for i,v in ipairs(a) do⤶
if (i ~= #a) then⤶
str = str .. v .. ", "⤶
else⤶
str = str .. v⤶
end⤶
end⤶
⤶
print(str) -- "a, b, c, d"⤶
```⤶
```lua⤶
--[[⤶
pairs() iteriates through all, but number indexes first and then all keys.⤶
However while the number indexes are in order, the key indexes are not. Lua does not guarantee the order of the key indexes.⤶
However, you can reinsert keys into a table and use table.sort()⤶
but it can not sort the way on how they were written up in the table.⤶
So don't rely on the position if the keys have a weird name. ⤶
--]]⤶
⤶
local str = ""⤶
local a = {"a", "b", "c", key = "e", key2 = "f", "d"}⤶
for k,v in pairs(a) do⤶
if not (next(a,k) == nil) then⤶
str = str .. v .. ", "⤶
else⤶
str = str .. v⤶
end⤶
end⤶
⤶
print(str) -- can output "a, b, c, d, e, f" or "a, b, c, d, f, e"⤶
```⤶
⤶
## C# ⤶
In C# for loops work differently.