public static void Run()
        {
            UClass unrealClass = UClass.GetClass <Test_SimpleFuncs>();

            Tests.Assert(unrealClass != null, "Test_SimpleFuncs");

            Test_SimpleFuncs obj = UObject.NewObject <Test_SimpleFuncs>();

            TestFuncX(obj, unrealClass, 1);
            TestFuncX(obj, unrealClass, 2);
            TestFuncX(obj, unrealClass, 3);
            TestResultFunctions(obj, unrealClass);
        }
        private static T TestResultFuncX <T>(Test_SimpleFuncs obj, int func, bool isNullResult)
        {
            string funcName = "ResultFunc" + func;

            if (isNullResult)
            {
                funcName += "_Null";
            }
            UFunction func1 = obj.GetClass().FindFunctionByName(new FName(funcName));

            Tests.AssertNotNull(func1, obj.GetClass(), funcName);

            return((T)UObject.DynamicInvoke(obj, funcName));
        }
        private static void TestResultFuncXEquals <T>(T value, Test_SimpleFuncs obj, int func, bool isNullResult)
        {
            UClass unrealClass = obj.GetClass();
            string funcName    = "ResultFunc" + func;

            if (isNullResult)
            {
                funcName += "_Null";
            }
            UFunction func1 = unrealClass.FindFunctionByName(new FName(funcName));

            Tests.AssertNotNull(func1, unrealClass, funcName);

            Tests.AssertEqual((T)UObject.DynamicInvoke(obj, funcName), value, unrealClass, funcName);
        }
        private static void TestResultFunctions(Test_SimpleFuncs obj, UClass unrealClass)
        {
            UClass actorClass = GetActorClass();

            TestResultFuncXEquals <sbyte>(4, obj, 1);
            TestResultFuncXEquals <byte>(5, obj, 2);
            TestResultFuncXEquals <short>(6, obj, 3);
            TestResultFuncXEquals <ushort>(7, obj, 4);
            TestResultFuncXEquals <int>(8, obj, 5);
            TestResultFuncXEquals <uint>(9, obj, 6);
            TestResultFuncXEquals <long>(10, obj, 7);
            TestResultFuncXEquals <ulong>(11, obj, 8);
            TestResultFuncXEquals <float>(12.3f, obj, 9);
            TestResultFuncXEquals <double>(13.4, obj, 10);
            Tests.Assert(TestResultFuncX <Test_SimpleDelegate>(obj, 11, false).IsBound, unrealClass, "ResultFunc11");
            Tests.AssertEqual(TestResultFuncX <Test_SimpleMulticastDelegate>(obj, 12, false).Count, 3, unrealClass, "ResultFunc12");
            TestResultFuncXEquals <UObject>(actorClass, obj, 13);
            TestResultFuncXEquals <UObject>(null, obj, 13, true);
            TestResultFuncXEquals <Test_SimpleEnum>(Test_SimpleEnum.Val3, obj, 14);

            var fixedArrayStruct = obj.ResultFunc15();

            Tests.AssertEqual(fixedArrayStruct.Array1[0], 2, unrealClass, "ResultFunc15");
            Tests.AssertEqual(fixedArrayStruct.Array1[1], 5, unrealClass, "ResultFunc15");
            Tests.AssertEqual(fixedArrayStruct.Array1[2], 111, unrealClass, "ResultFunc15");

            Tests.AssertEqual(TestResultFuncX <TSubclassOf <UObject> >(obj, 16, false).Value, actorClass, unrealClass, "ResultFunc16");
            Tests.AssertEqual(TestResultFuncX <TSubclassOf <UObject> >(obj, 16, true), TSubclassOf <UObject> .Null, unrealClass, "ResultFunc16");
            Tests.AssertEqual(TestResultFuncX <TLazyObject <UObject> >(obj, 17, false).Value, actorClass, unrealClass, "ResultFunc17");
            Tests.AssertEqual(TestResultFuncX <TLazyObject <UObject> >(obj, 17, true), TLazyObject <UObject> .Null, unrealClass, "ResultFunc17_Null");
            Tests.AssertEqual(TestResultFuncX <TWeakObject <UObject> >(obj, 18, false).Value, actorClass, unrealClass, "ResultFunc18");
            Tests.AssertEqual(TestResultFuncX <TWeakObject <UObject> >(obj, 18, true), TWeakObject <UObject> .Null, unrealClass, "ResultFunc18_Null");
            Tests.AssertEqual(TestResultFuncX <TSoftClass <UObject> >(obj, 19, false).Value, actorClass, unrealClass, "ResultFunc19");
            Tests.AssertEqual(TestResultFuncX <TSoftClass <UObject> >(obj, 19, true), TSoftClass <UObject> .Null, unrealClass, "ResultFunc19_Null");
            Tests.AssertEqual(TestResultFuncX <TSoftObject <UObject> >(obj, 20, false).Value, actorClass, unrealClass, "ResultFunc20");
            Tests.AssertEqual(TestResultFuncX <TSoftObject <UObject> >(obj, 20, true), TSoftObject <UObject> .Null, unrealClass, "ResultFunc20_Null");
            Tests.AssertEqual(TestResultFuncX <string>(obj, 21, false), "result", unrealClass, "ResultFunc21");
            Tests.AssertEqual(TestResultFuncX <string>(obj, 21, true), string.Empty, unrealClass, "ResultFunc21_Null");
            Tests.AssertEqual(TestResultFuncX <FName>(obj, 22, false), new FName("result"), unrealClass, "ResultFunc22");
        }
 private static void TestResultFuncXEquals <T>(T value, Test_SimpleFuncs obj, int func)
 {
     TestResultFuncXEquals(value, obj, func, false);
 }
        private static void TestFuncX(Test_SimpleFuncs obj, UClass unrealClass, int func)
        {
            string    funcName = "Func" + func;
            UFunction func1    = unrealClass.FindFunctionByName(new FName(funcName));

            Tests.AssertNotNull(func1, unrealClass, funcName);

            Test_SimpleDelegate simpleDelegate = new Test_SimpleDelegate();

            simpleDelegate.Bind(obj.BindMe);

            Test_SimpleMulticastDelegate multicastDelegate = new Test_SimpleMulticastDelegate();

            multicastDelegate.Bind(obj.BindMeMulti1);
            multicastDelegate.Bind(obj.BindMeMulti2);

            // Use dynamic invoke so that all parameters go through a full marshal between C#/native code
            object[] parameters =
            {
                (sbyte)2,          //sbyte
                (byte)3,           //byte,
                (short)4,          //short
                (ushort)5,         //ushort
                (int)6,            //int
                (uint)7,           //uint
                (long)8,           //long
                (ulong)9,          //ulong
                (float)10.2f,      //float
                (double)11.5,      //double
                simpleDelegate,    //delegate
                multicastDelegate, //multicast delegate
                obj,
                Test_SimpleEnum.Val3,
                new Test_FixedArrayInStruct()
                {
                    Array1 = new sbyte[2] {
                        2, 5
                    }
                },
                new TSubclassOf <UObject>(obj.GetClass()),
                new TLazyObject <UObject>(obj),
                TWeakObject <UObject> .Null,
                new TSoftClass <UObject>(obj.GetClass()),
                new TSoftObject <UObject>(obj),
                "Test123",
                new FName("321Test")
            };
            long result = (long)UObject.DynamicInvoke(obj, funcName, parameters);

            Tests.AssertEqual(result, 13232, unrealClass, funcName + " result");

            if (func > 1)
            {
                sbyte  p1  = (sbyte)parameters[0];
                byte   p2  = (byte)parameters[1];
                short  p3  = (short)parameters[2];
                ushort p4  = (ushort)parameters[3];
                int    p5  = (int)parameters[4];
                uint   p6  = (uint)parameters[5];
                long   p7  = (long)parameters[6];
                ulong  p8  = (ulong)parameters[7];
                float  p9  = (float)parameters[8];
                double p10 = (double)parameters[9];
                Test_SimpleDelegate          p11 = (Test_SimpleDelegate)parameters[10];
                Test_SimpleMulticastDelegate p12 = (Test_SimpleMulticastDelegate)parameters[11];
                UObject                 p13      = (UObject)parameters[12];
                Test_SimpleEnum         p14      = (Test_SimpleEnum)parameters[13];
                Test_FixedArrayInStruct p15      = (Test_FixedArrayInStruct)parameters[14];
                TSubclassOf <UObject>   p16      = (TSubclassOf <UObject>)parameters[15];
                TLazyObject <UObject>   p17      = (TLazyObject <UObject>)parameters[16];
                TWeakObject <UObject>   p18      = (TWeakObject <UObject>)parameters[17];
                TSoftClass <UObject>    p19      = (TSoftClass <UObject>)parameters[18];
                TSoftObject <UObject>   p20      = (TSoftObject <UObject>)parameters[19];
                string p21 = (string)parameters[20];
                FName  p22 = (FName)parameters[21];

                UClass actorClass = GetActorClass();

                Tests.AssertEqual(p1, 3, unrealClass, funcName + ".p1");
                Tests.AssertEqual(p2, 4, unrealClass, funcName + ".p2");
                Tests.AssertEqual(p3, 5, unrealClass, funcName + ".p3");
                Tests.AssertEqual(p4, 6, unrealClass, funcName + ".p4");
                Tests.AssertEqual(p5, 7, unrealClass, funcName + ".p5");
                Tests.AssertEqual(p6, 8u, unrealClass, funcName + ".p6");
                Tests.AssertEqual(p7, 9, unrealClass, funcName + ".p7");
                Tests.AssertEqual(p8, 10u, unrealClass, funcName + ".p8");
                Tests.AssertEqual(p9, 11.2f, unrealClass, funcName + ".p9");
                Tests.AssertEqual(p10, 12.5, unrealClass, funcName + ".p10");
                Tests.Assert(!p11.IsBound, unrealClass, funcName + ".p11");
                Tests.Assert(p12.IsBound, unrealClass, funcName + ".p12");
                Tests.AssertEqual(p12.Count, 3, unrealClass, funcName + ".p12");
                Tests.AssertEqual(p13, actorClass, unrealClass, funcName + ".p13");
                Tests.AssertEqual(p14, Test_SimpleEnum.Val2, unrealClass, funcName + ".p14");
                Tests.AssertEqual(p15.Array1[0], 2, unrealClass, funcName + ".p15");
                Tests.AssertEqual(p15.Array1[1], 5, unrealClass, funcName + ".p15");
                Tests.AssertEqual(p15.Array1[2], 100, unrealClass, funcName + ".p15");
                Tests.AssertEqual(p16.Value, actorClass, unrealClass, funcName + ".p16");
                Tests.AssertEqual(p17.Value, actorClass, unrealClass, funcName + ".p17");
                Tests.AssertEqual(p18.Value, actorClass, unrealClass, funcName + ".p18");
                Tests.AssertEqual(p19.Value, actorClass, unrealClass, funcName + ".p19");
                Tests.AssertEqual(p20.Value, actorClass, unrealClass, funcName + ".p20");
                Tests.AssertEqual(p21, "changed123", unrealClass, funcName + ".p21");
                Tests.AssertEqual(p22, new FName("321changed"), unrealClass, funcName + ".p22");
            }
        }