Github user FlorianHockmann commented on a diff in the pull request:
https://github.com/apache/tinkerpop/pull/757#discussion_r153126228
--- Diff:
gremlin-dotnet/src/Gremlin.Net/Process/Traversal/DefaultTraversal.cs ---
@@ -86,9 +87,61 @@ public void Reset()
}
/// <inheritdoc />
- public E Current => (E)TraverserEnumerator.Current?.Object;
+ public E Current => GetCurrent<E>();
- object IEnumerator.Current => Current;
+ object IEnumerator.Current => GetCurrent();
+
+ private TReturn GetCurrent<TReturn>()
+ {
+ var value = GetCurrent();
+ var returnType = typeof(TReturn);
+ if (value == null || value.GetType() == returnType)
+ {
+ // Avoid evaluating type comparisons
+ return (TReturn) value;
+ }
+ return (TReturn) GetValue(returnType, value);
+ }
+
+ private object GetCurrent()
+ {
+ // Use dynamic to object to prevent runtime dynamic conversion
evaluation
+ return TraverserEnumerator.Current?.Object;
+ }
+
+ /// <summary>
+ /// Gets the value, converting to the expected type when necessary
and supported.
+ /// </summary>
+ private static object GetValue(Type type, object value)
+ {
+ var genericType = type.GetTypeInfo().IsGenericType
+ ? type.GetTypeInfo().GetGenericTypeDefinition()
+ : null;
+ if (value is IDictionary dictValue && genericType ==
typeof(IDictionary<,>))
+ {
+ var keyType = type.GenericTypeArguments[0];
+ var valueType = type.GenericTypeArguments[1];
+ var mapType =
typeof(Dictionary<,>).MakeGenericType(keyType, valueType);
+ var result = (IDictionary)
Activator.CreateInstance(mapType);
+ foreach (DictionaryEntry kv in dictValue)
+ {
+ result.Add(GetValue(keyType, kv.Key),
GetValue(valueType, kv.Value));
+ }
+ return result;
+ }
+ if (value is IEnumerable enumerableValue && genericType ==
typeof(IList<>))
--- End diff --
I don't want to change the return types for the traversal API, but a user
can specify the type for some steps directly like you did in the added tests:
`ValueMap<IList<int>>`. When `ValueMap<List<int>>` is used instead then it
won't work right now.
---