Given a query input object used to provide filters for querying a database (CQRS) I'm never 100% sure how best to construct that object using IEnumerable<>, e.g., say we have a database that contains vehicles and I write a query that takes a GetVehiclesQueryInput that has some enumerable of vehicle ids as its input such that the query just returns those vehicles with matching id's (if the enumerable type is null, all vehicles are returned), e.g., in its simplest form we could have
public class GetVehiclesQueryInput {
public GetVehiclesQueryInput(IEnumerable<int> vehicleIds = null) {
VehicleIds = vehicleIds;
}
IEnumerable<int> VehicleIds { get; }
}
However, given this is a query it makes sense to me that the query is a 'snapshot' taken at the point in time the query is created, but given the IEnumerable injected there is the potential that the injected IEnumerable could be reference to a derived implementation (e.g. List) and coupled with the possibility of deferred execution may no longer be a 'snaphost' at the point in time the query is created. As such is it considered better practice to do something like:
public class GetVehiclesQueryInput {
public GetVehiclesQueryInput(IEnumerable<int> vehicleIds = null) {
VehicleIds = vehicleIds is null ? null : new ReadOnlyCollection<int>(vehicleIds .ToList());
}
IReadOnlyCollection<int> VehicleIds { get; }
}
or
public class GetVehiclesQueryInput {
public GetVehiclesQueryInput(IEnumerable<int> vehicleIds = null) {
VehicleIds = vehicleIds is null ? null : vehicleIds.ToImmutableList());
}
IImmutableList<int> VehicleIds { get; }
}