From 590e37e2e19583468b8a2e890449ee418d1d1d29 Mon Sep 17 00:00:00 2001 From: AndyHeap-NeoTech Date: Thu, 2 Oct 2025 14:50:33 +0100 Subject: [PATCH 1/2] Fix for incorrect reporting of a type mismatch when object mapping fails and a Vector type is involved. Before the fix the error reported when trying to map from, for example, a Vector to a Vector was: System.InvalidOperationException: The expected value `Neo4j.Driver.Vector`1[System.Single]` is different from the actual value `System.Collections.Generic.List`1[System.Single]` This was occurring because the ValueExtensions As method did not contain a clause for IVector, this caused the logic to fall through to the IEnumerable clause (which a vector implements) which converted the vector into a list, and then failed the type conversion on that list. Now that a clause for IVector is added you get the correct error. e.g. For the Vector -> Vector example: System.InvalidOperationException: The expected value `Neo4j.Driver.Vector`1[System.Single]` is different from the actual value `Neo4j.Driver.Vector`1[System.Double]` --- .../Neo4j.Driver/Public/Extensions/ValueExtensions.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Neo4j.Driver/Neo4j.Driver/Public/Extensions/ValueExtensions.cs b/Neo4j.Driver/Neo4j.Driver/Public/Extensions/ValueExtensions.cs index b24a4b825..5e02e00c9 100644 --- a/Neo4j.Driver/Neo4j.Driver/Public/Extensions/ValueExtensions.cs +++ b/Neo4j.Driver/Neo4j.Driver/Public/Extensions/ValueExtensions.cs @@ -149,6 +149,11 @@ public static T As(this object value) { return Convert.ChangeType(value, targetType).AsItIs(); } + + if (value is IVector) + { + return value.AsItIs(); + } // force to cast to a dict or list var typeInfo = targetType.GetTypeInfo(); From 56902a79269bc1d90197e55635b75d0eae15bb47 Mon Sep 17 00:00:00 2001 From: AndyHeap-NeoTech Date: Thu, 16 Oct 2025 14:35:28 +0100 Subject: [PATCH 2/2] Added tests to check on vector conversions in the valueExtensions class. Vectors should not be able to be converted to any other type, or between mismatched vectors. --- .../ValueExtensionsTests.cs | 24 +++++++++++++++++++ .../Public/Extensions/ValueExtensions.cs | 17 +++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/Neo4j.Driver/Neo4j.Driver.Tests/ValueExtensionsTests.cs b/Neo4j.Driver/Neo4j.Driver.Tests/ValueExtensionsTests.cs index 96c17b7db..f363dea0d 100644 --- a/Neo4j.Driver/Neo4j.Driver.Tests/ValueExtensionsTests.cs +++ b/Neo4j.Driver/Neo4j.Driver.Tests/ValueExtensionsTests.cs @@ -236,6 +236,30 @@ public void ShouldThrowExceptionWhenCastFromListToInt() var ex = Record.Exception(() => value.As()); ex.Should().BeOfType(); } + + [Fact] + public void ShouldThrowExceptionWhenCastFromVectorToNonVector() + { + object value = new Vector(new[] { 1.0f, 2.0f, 3.0f, 4.0f }); + var ex = Record.Exception(() => value.As()); + ex.Should().BeOfType(); + } + + [Fact] + public void ShouldThrowExceptionWhenCastFromNonVectorToVector() + { + object value = (int)10; + var ex = Record.Exception(() => value.As>()); + ex.Should().BeOfType(); + } + + [Fact] + public void ShouldThrowExceptionWhenCastingBetweenMismatchedVectors() + { + object value = new Vector(new[] { 1.0f, 2.0f, 3.0f, 4.0f }); + var ex = Record.Exception(() => value.As>()); + ex.Should().BeOfType(); + } } public class AsCollectionTypeMethod diff --git a/Neo4j.Driver/Neo4j.Driver/Public/Extensions/ValueExtensions.cs b/Neo4j.Driver/Neo4j.Driver/Public/Extensions/ValueExtensions.cs index 5e02e00c9..dba2181e2 100644 --- a/Neo4j.Driver/Neo4j.Driver/Public/Extensions/ValueExtensions.cs +++ b/Neo4j.Driver/Neo4j.Driver/Public/Extensions/ValueExtensions.cs @@ -150,10 +150,12 @@ public static T As(this object value) return Convert.ChangeType(value, targetType).AsItIs(); } + //If the source type (value) is a vector then it can not be cast to anything else. We also want to + //make sure that it is not attempting to cast into a vector of another type. if (value is IVector) { - return value.AsItIs(); - } + return AsVector(value); + } // force to cast to a dict or list var typeInfo = targetType.GetTypeInfo(); @@ -202,6 +204,17 @@ private static T AsList(this IEnumerable value, TypeInfo typeInfo) return list.AsItIs(); } + private static T AsVector(this object value) + { + if (value is T result) + { + return result; + } + + throw new InvalidCastException($"Cannot cast differing vector types. Attempting from `" + + $" { typeof(T) }` to `{value.GetType()}"); + } + #region Helper Methods private static object InvokeStatic(this MethodInfo method, params object[] parameters)