I have a Vehicle
object which has a few properties such as Make
, Model
, Price
, etc.
I also have a VehicleCollection
object which derives from List<Vehicle
which has a few custom methods, one of which is the following...
class VehicleCollection : List<Vehicle>
{
public VehicleCollection GetVehicles(string _searchTerm = "")
{
// return the entire collection if no search term is provided
if (_searchTerm.Length == 0)
return this;
var matchingVehicles = new VehicleCollection();
foreach(var vehicle in this) // loop through all vehicles
{
PropertyInfo[] propInfos = vehicle.GetType().GetProperties(); // all properties of the current vehicle
for (int i = 0; i < propInfos.Length; i++)
{
var propVal = propInfos[i].GetValue(vehicle); // the value of the current property of the current vehicle
// check aganst value of a strings or the values within a string array
// ignores case
if (propVal is string propertyValueStr && propertyValueStr.IndexOf(_searchTerm, StringComparison.CurrentCultureIgnoreCase) >= 0
|| propVal is string[] propValueArr && propValueArr.Any(x => x.IndexOf(_searchTerm, StringComparison.CurrentCultureIgnoreCase) >= 0))
{
matchingVehicles.Add(vehicle);
}
}
}
return matchingVehicles;
}
}
This returns a collection of vehicles, of which each vehicle must have a property whose value contains the supplied _searchTerm
parameter.
Is this the best way to do this? Can this be achieved using LINQ at all? Can this be done without reflection?
Edit: At the request of a comment, here is the Vehicle Class, with a few unnecessary methods omitted.
public class Vehicle
{
public string ID { get; private set; }
public string Make { get; private set; }
public string Model { get; private set; }
internal decimal Value { get; private set; }
public string Price { get { return string.Format("{0:C}", Value); } }
public VehicleColourEnum Colour { get; private set; }
internal StatusEnum Status { get; private set; }
public string State
{
get
{
switch (Status)
{
case StatusEnum.ComingSoon:
return "Coming Soon";
case StatusEnum.HasDeposit:
return "Has Deposit";
case StatusEnum.InStock:
return "In Stock";
case StatusEnum.Sold:
return "Sold";
case StatusEnum.Unknown:
default:
return "Unknown";
}
}
}
public Vehicle(string _make, string _model, decimal _value, VehicleColourEnum _colour = VehicleColourEnum.None, StatusEnum _status = StatusEnum.Unknown)
{
Make = _make;
Model = _model;
Value = _value;
Colour = _colour;
Status = _status;
ID = Guid.NewGuid().ToString("N");
}
}
Vehicle
class, and this would just be the current instance of theVehicleCollection
class, which is aList<Vehicle>
. Hopefully that helps and is what you were looking for. \$\endgroup\$ – Danny Goodall Mar 20 '18 at 10:55