/// <summary> /// Attempt to evaluate the specified source code. /// The provided source code will be compiled (unless cached) and then executed in <see cref="ScriptDomain"/> specified in the constructor. /// Any valid C# method body syntax is accepted. You may not define user types or methods in the provided source. Type declarations are allowed. /// </summary> /// <typeparam name="T">The generic type that the evaluated code should return</typeparam> /// <param name="sourceCode">The string source code to execute</param> /// <returns>A <see cref="Variable"/> representing the return value of the evaluated code. If the evaluated code does not return a value then the result will be a <see cref="Variable"/> representing 'default(T)'. If the code failed to run then the return value will be null</returns> public Variable <T> Eval <T>(string sourceCode) { ScriptProxy proxy = null; // Check whether this source is cached bool isCached = evalCache.ContainsKey(sourceCode); // Check if we have a cached version of this source code if (isCached == true) { // Get the cached type proxy = evalCache[sourceCode]; } else { // Get the full C# source code string source = BuildSourceAroundTemplate(sourceCode); #if UNITY_EDITOR && !UNITY_WEBPLAYER // Check if we should output the generated source if (outputGeneratedSourceIfDebug == true) { System.IO.File.WriteAllText("DynamicCSharp_Eval_GeneratedSource.cs", source); } #endif // Try to compile the code ScriptType type = domain.CompileAndLoadScriptSource(source); // Looks like we failed to compile or find a cached type if (type == null) { return(null); } // Create an instance proxy = type.CreateInstance(); // Check for error if (proxy == null) { return(null); } } // Check if we need to cache the type if (isCached == false) { // Make a cache entry evalCache.Add(sourceCode, proxy); } // Bind the delegates to the proxy BindProxyDelegates(proxy); // Bind the values to the proxy BindProxyVars(proxy); // Bind our return value object returnResult = new object(); proxy.Fields[returnObject] = returnResult; // Call the method object result = proxy.SafeCall(entryMethod); // Read the value back into evaluator memory space UnbindProxyVars(proxy); // Check if we returned a value if (returnResult == result) { return(new Variable <T>(returnObject, default(T))); } // Create a default error value that we can use if we fail to get the correct type T resolvedReturn = default(T); try { // Try to cast to type resolvedReturn = (T)result; } catch (InvalidCastException) { } // We successfully ran the code return(new Variable <T>(returnObject, resolvedReturn)); }