I have a simple interface, IDevice
public interface IDevice{
string Id{ get; }
}
I have a list of objects that implement IDevice
List<IDevice> devices;
An example of two of the types of objects in this list are:
public class BatteryDevice : IDevice{
public string Id{ get; private set; }
public int StateOfCharge{ get; set; }
}
public class GridDevice : IDevice{
public string Id{ get; private set; }
public decimal Voltage{ get; set; }
}
I want to allow the user to set a condition in text using a SQL query like this:
Id = 'Battery1' AND StateOfCharge > 95
So that I can read these conditions from a text config file and evaluate against the list of devices using dynamic LINQ like this:
var matches = devices.Where("Id = 'Battery1' AND StateOfCharge > 95");
This doesn't work because (of course) the LINQ would fail when trying to get a value for StateOfCharge
from the GridDevice
I'm feeling like a bit of a n00b and looking for a way to achieve my goal and would appreciate any input.
You can write:
var matches = devices
.OfType<BatteryDevice>()
.Where(device => device.Id == "Battery1" && device.StateOfCharge > 95)
.ToList();
It selects all devices from the List
of IDevice
of type BatteryDevice
having matching desired condition and returns a List<BatteryDevice>
having items of the resulting Linq query sequence.
You can use ToList
or not depending of what you plan to do with the result.
If not the result is type of IEnumerable<BatteryDevice>
.
To have a List
of IDevice
you can use:
.ToList<IDevice>();
Or you can write:
var matches = (IEnumerable<IDevice>)devices...
Without Linq
var matches = new List<IDevice>();
foreach ( var device in devices )
if ( device is BatteryDevice )
{
var battery = (BatteryDevice)device;
if ( battery.Id == "Battery1" && battery.StateOfCharge > 95 )
matches.Add(battery);
}