Is dynamic linq suitable for this scenario?

c# dynamic-linq interface linq

Question

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.

1
0
11/6/2019 1:45:08 PM

Popular Answer

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);
  }
2
11/6/2019 2:33:02 PM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow