sovr610 / luainterface

Automatically exported from code.google.com/p/luainterface
1 stars 0 forks source link

Dynamic member access not working. Receiving field not found errors #54

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create class and derive from System.Dynamic
2. Override TrySetMember, TryGetMember and GetDynamicMemberNames
3. Create an instance of the Dynamic class
4. Place the dynamic object as a variable in LuaInterface.Lua
5. Try and set a field in the dynamic object with LuaScript

What is the expected output?
1. LuaInterface should call TrySetMember in the Dynamic object

What do you see instead?
1. "field or property '" + fieldName + "' does not exist"

What version of the product are you using?
1. Latest SVN download for LuaInterface

On what operating system?
1. .Net 4.0

Please provide any additional information below.

Original issue reported on code.google.com by coray...@gmail.com on 14 Nov 2012 at 12:32

GoogleCodeExporter commented 9 years ago
Here is source console app to show problem with dynamic objects:

using System;
using System.Collections.Generic;
using System.Dynamic;

namespace ConsoleApplication1
{
    class Program
    {
        static string Script =
            @"

            e:Print(e.Firstname);
            e.Age=20;

            ";

        static void Main(string[] args)
        {
            dynamic e = new Entity();
            e.Firstname = "Matt";
            e.Age = 29;

            LuaInterface.Lua Lua = new LuaInterface.Lua();
            Lua["e"] = e;

            Lua.DoString(Script, "");

            e.Dispose();
            Lua.Dispose();
            Console.ReadLine();
        }
    }

    class Entity : DynamicObject, IDisposable
    {
        Dictionary<string, object> Members = null;

        public Entity()
        {
            Members = new Dictionary<string,object>();
        }

        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return Members.Keys;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (Members.ContainsKey(binder.Name))
            {
                result = Members[binder.Name];
                return true;
            }
            else
            {
                result = null;
                return false;
            }
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            Members[binder.Name] = value;
            return true;
        }

        public void  Dispose()
        {
            foreach (KeyValuePair<string, object> Member in Members)
            {
                if (Member.Value.GetType() is IDisposable)
                {
                    IDisposable DisposableMember = (IDisposable)Member.Value;
                    DisposableMember.Dispose();
                }
            }

            Members.Clear();
            Members = null;
        }

        public void Print(string Message)
        {
            Console.WriteLine(Message);
        }
    }
}

Original comment by coray...@gmail.com on 14 Nov 2012 at 1:34

GoogleCodeExporter commented 9 years ago
You would expect the Console to print 'Matt' from a call to TryGetMember in the 
Entity Object.

Instead, the variable name is printed.

You then expect e.Age to be set to 29 by the Lua script. Instead an error is 
thrown for an missing member.

Original comment by coray...@gmail.com on 14 Nov 2012 at 1:36