简体   繁体   English

为什么 LINQ 找不到具有包含特定子字符串的属性的项目?

[英]Why LINQ can't find the item with property that Contains specific substring?

My application receive Messages list from server.我的应用程序从服务器接收消息列表。 Message object has 'Text' property.消息对象具有“文本”属性。 From this list I was trying to find first item where 'Text' contains specific substring.从这个列表中,我试图找到“文本”包含特定子字符串的第一项。 For example response could contains such elements in list(sequence saved):例如,响应可以在列表中包含这样的元素(序列保存):

Text = "mye:service?resp=out&text=some_text&id=854217";
Text = "mye:service?resp=inj&text=some_text&id=854219";
Text = "mye:service?resp=corr&text=some_text&id=854220";
Text = "mye:service?resp=out&text=some_text&id=854223";
Text = "mye:service?resp=inj&text=some_text&id=854227";
Text = "mye:service?resp=corr&text=test&id=854230";

Here is how I attempting to get the right item:这是我尝试获得正确物品的方法:

Message suitableMessage = messagesList.FirstOrDefault(m => m.Text.Contains("param") || m.Text.Contains("corr"));

It always returns first element, this one:它总是返回第一个元素,这个:

Text = "mye:service?resp=out&text=some_text&id=854217";

Viewing list items in the debugger, I see that there are suitable elements.在调试器中查看列表项,我看到有合适的元素。

What am I doing wrong?我究竟做错了什么?

You are using .FirstOrDefault() (First or null if not found in your case), why do you excpeted to get something different than the first match?您正在使用.FirstOrDefault() (如果在您的情况下未找到,则为 First 或null ),为什么您会得到与第一个匹配不同的东西?

If you want to get an array (or more accurately an IEnumerable ) of all matches, use .Where() instead.如果您想获取所有匹配项的数组(或更准确地说是IEnumerable ),请改用.Where()

If you run this example you will see that LinQ works as expected:如果您运行此示例,您将看到 LinQ 按预期工作:

    static void Main(string[] args)
    {
        var messagesList = new List<Message>
        {
            new Message {Text = "mye:service?resp=out&text=some_text&id=854217"},
            new Message {Text = "mye:service?resp=inj&text=some_text&id=854219"},
            new Message {Text = "mye:service?resp=corr&text=some_text&id=854220"},
            new Message {Text = "mye:service?resp=out&text=some_text&id=854223"},
            new Message {Text = "mye:service?resp=inj&text=some_text&id=854227"},
            new Message {Text = "mye:service?resp=corr&text=test&id=854230"}
        };

        Message suitableMessage = messagesList.FirstOrDefault(m => m.Text.Contains("param") || m.Text.Contains("corr"));
        //result:
        //suitableMessage == "mye:service?resp=corr&text=some_text&id=854220"

        //verification
        if (suitableMessage.Text.Contains("param"))
        {
            Console.WriteLine("param");
        }

        if (suitableMessage.Text.Contains("corr"))
        {
            Console.WriteLine("corr");
        }

        //verification 2 - you can replace your LinQ with this code and debug
        Message suitableMessage2;
        string reason;
        string text; // just to make sure that value is not changed by some other thread ...
        foreach (var m in messagesList)
        {
            if (m.Text.Contains("param"))
            {
                suitableMessage2 = m;
                text = m.Text;
                reason = "param";
                break;
            }

            if (m.Text.Contains("corr"))
            {
                suitableMessage2 = m;
                text = m.Text;
                reason = "corr";
                break;
            }
        }

        // verification 3 - replace lambda with method if not sure how to add break point, write logs if cant debug runtime
        Message suitableMessage3 = messagesList.FirstOrDefault(DebugLinq);


        Console.ReadKey();
    }

    private static bool DebugLinq(Message m)
    {
        if (m.Text.Contains("param"))
        {
            // log Text, "param"
            return true;
        }

        if (m.Text.Contains("corr"))
        {
            // log Text, "corr"
            return true;
        }

        return false;
    }

Thanks to all involved.感谢所有参与的人。 All because of my inattention, and incorrect names of extension methods.都是因为我的疏忽,以及扩展方法的错误名称。 In one of the libraries used in the project there is an extension method for the list which is called "FirstOrDefult".在项目中使用的一个库中,有一个名为“FirstOrDefult”的列表扩展方法。 This method, apparently, in my case always returns the first element.显然,在我的例子中,这个方法总是返回第一个元素。 Including LINQ namespace did the trick, and now all works as expected包含 LINQ 命名空间可以解决问题,现在一切都按预期工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM