Question

See the code below for my dilema. I have an object with a method that returns a count of items in an IList (CountChildren) which works fine. But another that does the same thing but taking in a generic (CountGenericChildren) does not. I get "System.NullReferenceException : Object reference not set to an instance of an object" on the line running the script (see comments). The last 2 Asserts are not executed.

I believe this has something to do with passing generics as parameters, but my knowledge of IronRuby is extremely limited. Any help would be appreciated. C# v3.5, IronRuby v1.0

    [Test]
    public void TestIronRubyGenerics()
    {
        string script = null;
        object val;
        ScriptRuntime _runtime;
        ScriptEngine _engine;
        ScriptScope _scope;

        _runtime = Ruby.CreateRuntime();
        _engine = _runtime.GetEngine("ruby");
        _scope = _runtime.CreateScope();

        _scope.SetVariable("parentobject", new ParentObject());


        // non-generic
        script = "parentobject.CountChildren(parentobject.Children)";
        val = _engine.CreateScriptSourceFromString(script, SourceCodeKind.Expression).Execute(_scope);
        Assert.IsTrue(val is int);
        Assert.AreEqual(2, val);

        // generic - this returns correctly
        script = "parentobject.GenericChildren";
        val = _engine.CreateScriptSourceFromString(script, SourceCodeKind.Expression).Execute(_scope);
        Assert.IsTrue(val is IList<ChildObject>);

        // generic - this does not
        script = "parentobject.CountGenericChildren(parentobject.GenericChildren)";
        val = _engine.CreateScriptSourceFromString(script, SourceCodeKind.Expression).Execute(_scope);
        Assert.IsTrue(val is bool);
        Assert.AreEqual(2, val);
        return;
    }

    internal class ParentObject
    {
        private IList<ChildObject> list;

        public ParentObject()
        {
            list = new List<ChildObject>();
            list.Add(new ChildObject());
            list.Add(new ChildObject());
        }

        public IList<ChildObject> GenericChildren
        {
            get
            {
                return list;
            }
        }

        public IList Children
        {
            get
            {
                IList myList = new System.Collections.ArrayList(list.Count);
                foreach(ChildObject o in list)
                    myList.Add(o);
                return myList;
            }
        }

        public int CountGenericChildren(IList<ChildObject> c)
        {
            return c.Count;
        }

        public int CountChildren(IList c)
        {
            return c.Count;
        }
    }

    internal class ChildObject
    {
        public ChildObject()
        {
        }
    }
Was it helpful?

Solution

That is an IronRuby bug. To workaround it, change the CountGenericChildren method to receive List instead of IList:

public int CountGenericChildren(List<ChildObject> c)
{
  return c.Count;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top