[
https://issues.apache.org/jira/browse/TINKERPOP-1837?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16266793#comment-16266793
]
ASF GitHub Bot commented on TINKERPOP-1837:
-------------------------------------------
Github user FlorianHockmann commented on a diff in the pull request:
https://github.com/apache/tinkerpop/pull/757#discussion_r153193506
--- 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 --
Ok, then lets leave it as it is in this PR. We can still change it in case
it leads to problems for users.
> Gremlin .NET: Provide type coercion between IDictionary<K, V> instances
> -----------------------------------------------------------------------
>
> Key: TINKERPOP-1837
> URL: https://issues.apache.org/jira/browse/TINKERPOP-1837
> Project: TinkerPop
> Issue Type: Improvement
> Components: dotnet
> Affects Versions: 3.3.0, 3.2.6
> Reporter: Jorge Bay
> Assignee: Jorge Bay
> Fix For: 3.2.7, 3.3.1
>
>
> As [described on the mailing
> list|https://lists.apache.org/thread.html/368c4aa3b37ef9628a3af612aece93fe9ca1914e3b3393e7e2e9fbdd@%3Cdev.tinkerpop.apache.org%3E],
> the limitation for of the specification combined with the strictness of .NET
> generics, makes dealing with maps on the .NET GLV hard / impossible.
> All methods returning a map have this issue, as in the following example:
> {code}
> IDictionary<string, IList<int>> result =
> g.V().ValueMap<IList<int>>("age").Next();
> {code}
> Causes an exception at runtime:
> {code}
> System.InvalidCastException: Unable to cast object of type
> 'System.Collections.Generic.Dictionary`2[System.Object,System.Object]' to
> type
> 'System.Collections.Generic.IDictionary`2[System.String,System.Collections.Generic.IList`2[System.Int32]]'.
> {code}
> We should provide conversion mechanism inside the default traversal.
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)