使用Linq从Enum中选择

问题描述 投票:-1回答:3

我在一个对象ChannelName和ChannelValue中有两个属性。我有一个包含频道ID列表的枚举。

我希望能够使用Linq查询来说“选择通道名称=枚举中的一个项目的通道值”。

到目前为止,我有这个,但我收到错误:

无法将类型'System.Collections.Generic.IEnumerable'隐式转换为'string'

代码是:

 var channels = Enum.GetNames(typeof(ModbusChannels)).ToList();
            var allChannelValues = "";

            foreach (var item in channels)
            {
                allChannelValues = (from x in data where x.ChannelName.Contains(item) select x.ChannelValue);
            }

仅供参考,其中“数据”出现在查询中,这是一个完全填充的对象。

Enum有500个名字,但这里有一个缩短的版本:

 public enum ModbusChannels{
        M0,
        M1,
        M2,
        M3,
        M4,
        M5,
        M6,
        M7,
        M8
}

这是正确的方法,我如何实现查询。

c# linq enums
3个回答
3
投票

您可以使用Contains检查枚举值是否包含通道名称:

var channels = Enum.GetNames(typeof(ModbusChannels)).ToList();
var allChannelValues = data.Where(d => channels.Contains(d.ChannelName)).ToList();

1
投票

我正在阅读你的问题的方式是你想看看属性ChannelName的字符串值是否作为枚举ModbusChannels中的名称存在。

List<string> channels = Enum.GetNames(typeof(ModbusChannels)).ToList();
var allChannelValues = data
                   .Where(x => channels.Contains(x.ChannelName))
                   .Select(x => x.ChannelValue)
                   .ToList();

如果此字符串值包含多个值(如CSV字符串),则无效。在这种情况下,如果包含样本值,则会更清楚。


1
投票

这个错误的原因是因为allChannelValuesstring类型,而你试图分配给from x in data ...allChannelValues表达式导致IEnumerable<ChannelValueType>,其中ChannelValueTypex.ChannelValue的类型相同。正如错误所述,IEnumerable<ChannelValueType>不能隐式转换为string存储在allChannelValues中。

其他答案提供了一种更有效的方法来做到这一点,但只是为了“完成你已经开始做的事情的想法”......

List<string> channels = Enum.GetNames(typeof(ModbusChannels)).ToList();
IEnumerable<ChannelValueType> allChannelValues = Enumerable.Empty<ChannelValueType>();

foreach (string item in channels)
{
    IEnumerable<ChannelValueType> channelValues = from x in data
                                                  where x.ChannelName.Contains(item)
                                                  select x.ChannelValue;

    allChannelValues = allChannelValues.Concat(channelValues);
}

string allChannelValuesText = string.Join(", ", allChannelValues);

使用适当的类型声明allChannelValues是消除错误所需的全部内容。

您还在allChannelValues的每次迭代中分配foreach,因此在循环完成时,allChannelValues将包含仅最后一次迭代的结果。相反,我们将查询结果存储在channelValues中,然后将其连接到allChannelValues以保存循环的累积结果; allChannelValuesempty enumerable初始化,因此在第一次迭代时有一些东西可以调用.Concat()

最后,我们使用string.Join()构建一个逗号分隔的string得到的ChannelValue值。直到执行此行,才会实际评估foreach块中的LINQ查询/方法,但这不会影响结果。

© www.soinside.com 2019 - 2024. All rights reserved.