Does Scriban support .NET Object Indexers ?
CADbloke opened this issue · 3 comments
Firstly, thanks for this awesome library. I am investigating using it in an app that will retrieve data for CAD drawings of wiring diagrams for television stations, just in case you thought you'd heard every use-case.
My question: does the .NET object property retrieval support class indexers like Thing["Index"] where Index isn't an actual property but rather the argument for an indexer lookup? For a MSFT example on indexers - https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/indexers/using-indexers#example-2
cheers
I think I can answer my own question here: "not yet" and "looks tricky". Or it does and I missed it,
Looking at https://github.com/lunet-io/scriban/blob/63ad634ffaf55cd4b8e72d1342f979520934c5be/src/Scriban/Runtime/Accessors/TypedObjectAccessor.cs at TryGetValue is only looks up fields and properties.
I found https://stackoverflow.com/questions/14462820/check-if-indexing-operator-exists/14462921#14462921 for reference on indexers and how to find it.
related: #116
I tried adding this code to TryGetValue ...
var indexer = _type.GetProperties().FirstOrDefault(p => p.GetIndexParameters().Length != 0
&& !typeof(IList).IsAssignableFrom(_type));
if (indexer != null)
{
object[] indexArgs = { member };
try
{
value = indexer.GetValue(target, indexArgs);
}
catch (Exception )
{
return false;
}
return true;
}
return false;but it broke .NET standard v1 & it also bypasses any filters etc. so it's not pull-request worthy.
Severity Code Description Project File Line Suppression State
Error CS1061 'Type' does not contain a definition for 'GetProperties' and no accessible extension method 'GetProperties' accepting a first argument of type 'Type' could be found (are you missing a using directive or an assembly reference?) Scriban(netstandard1.1), Scriban(netstandard1.3) D:\CodezOnD\Github\scriban\src\Scriban\Runtime\Accessors\TypedObjectAccessor.cs 63 Active
I added this test to https://github.com/lunet-io/scriban/blob/548998cbebb27534dcd36526ab0f2535ea81c237/src/Scriban.Tests/TestRuntime.cs (at line 730)
[Test]
public void TestIndexerOnNETwithIndex()
{
var myobject = new MyObjectHasIndexer() { FieldA = "yo"};
var result = Template.Parse("{{obj['xxx']}}").Render(new ScriptObject() {{"obj", myobject}});
Assert.AreEqual("found", result);
}
private class MyObjectHasIndexer : MyStaticObject
{
public string FieldA;
public string FieldB;
public string PropertyA { get; set; }
public string PropertyB { get; set; }
public string this[string key]
{
get
{
if (key == "xxx")
return "found";
return null;
}
set{}
}
}and it passed in .NET 3.5. but everything else seems broken. Oops
Your thoughts?
Thank you!
Sorry about my delay in responding. This is much appreciated. I will put together some tests of the way I plan to implement it and let you know how I go. It will probably me a couple of months before I have my shit together but this definitely opens up a lot of possibilities.
Thanks again
Ewen