S&box Wiki

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.