I am running into a very strange issue where I cannot use the indexer of an IReadOnlyCollection when it is exposed via an interface property. Below is a code example of the problem. The second line of the script results in TypeError: Cannot read property 'SystemName' of undefined. E.g. the indexer is returning undefined. It seems like the indexer should work regardless of if I am accessing the host object directly or via an interface.
>
public interface IDataObject
{
Guid Id { get; set; }
string SystemName { get; set; }
string DisplayName { get; set; }
string Description { get; set; }
IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get; }
}
public class DataObject : IDataObject
{
public DataObject()
{
Children = new List<SubDataObject>();
}
public Guid Id { get; set; }
public string SystemName { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get { return Children; } }
public Char CharTest { get; set; }
public int IntTest { get; set; }
public decimal DecimalTest { get; set; }
public byte ByteTest { get; set; }
public bool? BoolTest { get; set; }
public List<SubDataObject> Children { get; set; }
public string IntTestToString()
{
return IntTest.ToString();
}
public Func<string> DoSomething { get; set; }
}
public class SubDataObject
{
public DataObject Parent { get; set; }
public Guid Id { get; set; }
public string SystemName { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
}
private static void ReproduceIReadOnlyCollectionIssue()
{
var dataObj = new DataObject
{
Id = Guid.NewGuid(),
SystemName = "Root Object System Name",
DisplayName = "Root Object Display Name",
Description = "Root Description",
};
dataObj.Children = new List<SubDataObject>
{
new SubDataObject
{
Parent = dataObj,
Id = Guid.NewGuid(),
SystemName = "Sub System Name 0",
DisplayName = "Sub Display Name 0",
Description = "Sub Description 0"
}
};
using (var engine = new V8ScriptEngine())
{
engine.AddHostType("Console", typeof(Console));
engine.AddHostObject("dataObj", dataObj);
engine.AddHostObject("readOnlyCollection", dataObj.ChildrenReadOnly);
const string script = @"
Console.WriteLine(readOnlyCollection[0].SystemName); //works fine
Console.WriteLine(dataObj.ChildrenReadOnly[0].SystemName); //indexer returns undefined.
";
engine.Execute(script);
}
}
>
public interface IDataObject
{
Guid Id { get; set; }
string SystemName { get; set; }
string DisplayName { get; set; }
string Description { get; set; }
IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get; }
}
public class DataObject : IDataObject
{
public DataObject()
{
Children = new List<SubDataObject>();
}
public Guid Id { get; set; }
public string SystemName { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public IReadOnlyCollection<SubDataObject> ChildrenReadOnly { get { return Children; } }
public Char CharTest { get; set; }
public int IntTest { get; set; }
public decimal DecimalTest { get; set; }
public byte ByteTest { get; set; }
public bool? BoolTest { get; set; }
public List<SubDataObject> Children { get; set; }
public string IntTestToString()
{
return IntTest.ToString();
}
public Func<string> DoSomething { get; set; }
}
public class SubDataObject
{
public DataObject Parent { get; set; }
public Guid Id { get; set; }
public string SystemName { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
}
private static void ReproduceIReadOnlyCollectionIssue()
{
var dataObj = new DataObject
{
Id = Guid.NewGuid(),
SystemName = "Root Object System Name",
DisplayName = "Root Object Display Name",
Description = "Root Description",
};
dataObj.Children = new List<SubDataObject>
{
new SubDataObject
{
Parent = dataObj,
Id = Guid.NewGuid(),
SystemName = "Sub System Name 0",
DisplayName = "Sub Display Name 0",
Description = "Sub Description 0"
}
};
using (var engine = new V8ScriptEngine())
{
engine.AddHostType("Console", typeof(Console));
engine.AddHostObject("dataObj", dataObj);
engine.AddHostObject("readOnlyCollection", dataObj.ChildrenReadOnly);
const string script = @"
Console.WriteLine(readOnlyCollection[0].SystemName); //works fine
Console.WriteLine(dataObj.ChildrenReadOnly[0].SystemName); //indexer returns undefined.
";
engine.Execute(script);
}
}