我需要创建一个包含设备对象的列表。这些对象具有描述其名称,单位和转换的属性。转换有点特殊,因为它应该是一个函数。例如:如果我有一个以华氏度进行测量的温度传感器,则其转换方法应以摄氏度为单位计算并返回该值。而且,如果我有湿度传感器,其转换会有所不同,等等。以下是我尝试执行此操作的示例,但它不起作用。我收到错误消息,指出仅允许在“转换”上进行分配。
private class Device
{
public string Name { get; set; }
public Action Conversion { get; set; }
public string Unit { get; set; }
}
public static object ParseDecentLab(byte[] bytes)
{
List<Device> deviceList = new List<Device>()
{
new Device()
{
Name = "battery-voltage",
Conversion = (x) => x / 1000,
Unit = "V"
},
new Device()
{
Name = "air-temperature",
Conversion = (x) => (175 * x / 65535) - 45,
Unit = "°C"
}
};
答案 0 :(得分:0)
尝试以下代码:
使用Func
而不是Action
。
Func可以在操作无法执行的地方返回值。
private class Device
{
public string Name { get; set; }
public Func<double,double> Conversion { get; set; }
public string Unit { get; set; }
}
public static object ParseDecentLab(byte[] bytes)
{
List<Device> deviceList = new List<Device>()
{
new Device()
{
Name = "battery-voltage",
Conversion = (x) => x / 1000,
Unit = "V"
},
new Device()
{
Name = "air-temperature",
Conversion = (x) => (175 * x / 65535) - 45,
Unit = "°C"
}
};
}
答案 1 :(得分:0)
您想要Func<double, double>
而不是Action
;给定double
(例如4.5
伏)返回double
。
x => x / 1000
相反,Action
不接受任何参数,不返回任何值:() => {...}
代码:
// Let's implement immutable class (assigned once, never change)
// in order to prevent occasional errors like device.Name = ...
private class Device {
public string Name { get; }
public Func<double, double> Conversion { get; }
public string Unit { get; }
// Let's validate the input (at least, for null)
public Device(string name, Func<double, double> conversion, string unit) {
if (null == name)
throw new ArgumentNullException(nameof(name));
else if (null == conversion)
throw new ArgumentNullException(nameof(conversion));
else if (null == unit)
throw new ArgumentNullException(nameof(unit));
Name = name;
Conversion = conversion;
Unit = unit;
}
}
...
List<Device> deviceList = new List<Device>() {
new Device("battery-voltage", x => x / 1000, "V"),
new Device("air-temperature", x => (175 * x / 65535) - 45, "°C"),
};
可能的用法:
// What device should we use if we want °C unit?
Device temperature = deviceList
.FirstOrDefault(item => item.Unit == "°C");
byte[] dataToConvert = new byte[] {123, 45, 79};
// Device found
if (temperature != null) {
// Converting: for each value in dataToConvert we obtain corresponding t value
foreach (var value in dataToConvert) {
double t = temperature.Conversion(value);
...
}
}
或者借助 Linq ,您甚至可以拥有一组转换后的值(double[]
):
byte[] dataToConvert = new byte[] {123, 45, 79};
// Let's throw exception if device has not been found
Device temperature = deviceList
.First(item => item.Unit == "°C");
double[] results = dataToConvert
.Select(v => temperature.Convert(v))
.ToArray();