S&box Wiki

Revision Difference

From_Lua_to_CSharp#530474

<cat>Code.Misc</cat> <title>From Lua to C#</title> # What is this guide This is meant to give an idea of some major differences between Lua and C#. This isn't a complete guide to C# and it doesn't cover many of the topics. It's meant to be brief, simple and illustrative. If you want to learn C# in more depth, you can use the [official C# language reference](https://docs.microsoft.com/en-us/dotnet/csharp/). # Comments # Terminology ## Tables C# has no tables. Although they are not exactly a replacement, in most cases you will use *classes* instead. ## Variables In C# only variables defined in methods are called so. If it's defined in a class it is called a *field* instead. Example: ```csharp public class Player { private int _health; // field public void Damage(int amount, int times) { var totalAmount = amount * times; // variable } } ``` ## Functions In C# they are called *methods* instead. # 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 ``` C# has no global variables. But in most cases you can use static variables instead: C# has no global variables. But in most cases you can use static fields instead: ```csharp public class MyClass { // in C# globals need to be in a class public static int StaticField = 100; } // you can call the field by using MyClass.StaticField now. ``` # Type System Keep in mind that static fields are often easily abused and should be avoided as they make it harder to manage state correctly. In other words this will make your code more prone to bugs. # Type System Lua is a so called dynamic typed language. That means variables do not have a specific type and can be assigned any type of value. ```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 ``` C# is a static typed language. That means a variable has a known type that is set during its declaration. Only compatible values can be assigned. For example, you cannot assign a string value to an int variable. ```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 // operator 'as' converts an object reference or returns 'null' on failure var vehicle = new Car() as Vehicle; // downcast Car reference to Vehicle 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 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 ]] 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 "; // putting '@' before a string literal makes it a verbatim string literal 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 ); // 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 arr = { 'a', 'b', 'c' } print( arr[1] ) -- will print 'a' since array indices in Lua start from 1 ``` ```csharp var numbers = new int[3] { 1, 2, 3 }; var strings = new List<string> { "Oh", "Hi", "Mark" }; var functions = new Dictionary<string, Action> { ["myFunc"] = () => { } }; var arr = new string[3] { "a", "b", "c" }; Console.WriteLine(arr[1]); // will print "b" since array indices in C# like most languages start from 0 ``` # 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 ) -- b = 10, a = 5, c = 15 end ``` ```csharp for ( var i = 1; i < 10; i += 2 ) { Console.WriteLine( i ); // 1, 3, 5, 7, 9 } var a = 10; do { Console.WriteLine( a ); // 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() { ... } } ``` ```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 } } ```