Skip to content

Cast<T> and OfType<T>

Both methods change the C# element type of a traversal, but only one of them adds anything to the Gremlin query sent to the server.

OfType<T>() Cast<T>()
Gremlin step emitted hasLabel('...') (nothing)
Effect filters by label reasserts type only
Use when the result set may contain other types the traversal already guarantees the type

OfType<T>() — server-side label filter

OfType<T>() appends a hasLabel('...') step to the query, filtering the traversal to only those graph elements whose server-side label matches the Gremlinq model registration for T. Elements of other types are discarded by the database before any results are returned.

Narrowing after an edge traversal

Out<TEdge>() and In<TEdge>() return IVertexGremlinQuery<Vertex> because the destination vertex type is unknown at compile time. Use OfType<T>() to filter down to the expected concrete type.

C#
// Out<Route>() returns IVertexGremlinQuery<Vertex>.
// OfType<Airport>() adds hasLabel('Airport') to filter server-side.
_g.V<Airport>()
    .Out<Route>()
    .OfType<Airport>();
Narrowing all vertices

V() returns every vertex in the graph. OfType<T>() restricts the result to elements with the matching label.

C#
// V() returns all vertices as IVertexGremlinQuery<Vertex>.
// OfType<Airport>() narrows the result to Airport elements server-side.
_g.V()
    .OfType<Airport>();

OfType<T>() also accepts multiple type arguments (up to sixteen), emitting a single hasLabel('A', 'B', …) step and returning IVertexGremlinQuery<object>.

Cast<T>() — compile-time type assertion

Cast<T>() emits no Gremlin step. It is a pure C# operation that rebuilds the query with a different type parameter, giving you access to a typed API without asking the server to filter anything.

Asserting the destination type after an edge traversal

When the graph model guarantees that the vertices on the other side of an edge are all of a known type, Cast<T>() gives you the strongly-typed query without the extra hasLabel round-trip.

C#
// Cast<Airport>() does NOT add hasLabel — it is a pure C# type assertion.
// The traversal emits exactly the same Gremlin as without the Cast.
_g.V<Airport>()
    .Out<Route>()
    .Cast<Airport>();
Accessing the typed API after lookup by id

When you already constrain elements by identity or by another filter, there is no need for an additional label check. Cast<T>() unlocks the typed .Where(), .Values(), and other strongly-typed steps.

C#
// V("jfk") already constrains the element by identity — no label filter is needed.
// Cast<Airport>() makes the typed API available without adding hasLabel('Airport').
_g.V("jfk")
    .Cast<Airport>()
    .Where(a => a.Country == "US");

Warning

Cast<T>() does not filter. If the traversal returns elements of mixed types, all of them reach the deserializer. Only OfType<T>() provides an actual server-side filter that discards non-matching elements before they leave the database.