使用Linq从Enum中选择

时间:2018-09-04 17:31:48

标签: c# linq enums

我在一个对象中有两个属性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);
            }

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

枚举中有500个名字,但这是一个简短的版本:

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

这是执行此操作的正确方法,以及如何实现查询。

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分: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字符串),则此方法将无效。在这种情况下,如果您包含样本值,将会更加清楚。

答案 2 :(得分:1)

该错误的原因是因为allChannelValues的类型为string,而您尝试分配给from x in data ...的{​​{1}}表达式会导致{{1} },其中allChannelValuesIEnumerable<ChannelValueType>的类型相同。由于出现错误,无法将ChannelValueType隐式转换为x.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使用empty enumerable进行了初始化,因此在第一次迭代时需要调用.Concat()

最后,我们使用string.Join()来以逗号分隔的allChannelValues值作为结果allChannelValues的值。直到执行此行后,string块中的LINQ查询/方法才被实际评估,但这不会影响结果。