我的应用程序从服务器接收消息列表。消息对象具有“文本”属性。从这个列表中,我试图找到第一项,其中“文本”包含特定的子字符串。 例如,响应可能在列表中包含此类元素(已保存顺序):
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";
这是我尝试获取正确商品的方式:
Message suitableMessage = messagesList.FirstOrDefault(m => m.Text.Contains("param") || m.Text.Contains("corr"));
它总是返回第一个元素,这个元素:
Text = "mye:service?resp=out&text=some_text&id=854217";
在调试器中查看列表项,我发现有合适的元素。
我在做什么错了?
答案 0 :(得分:0)
您使用的是.FirstOrDefault()
(如果找不到您的案例,则是第一个或null
),为什么要争相获得与第一个匹配项不同的东西?
如果要获取所有匹配项的数组(或更准确地说是IEnumerable
),请改用.Where()
。
答案 1 :(得分:0)
如果运行此示例,您将看到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;
}
答案 2 :(得分:0)
感谢所有相关人员。都是由于我的注意力不集中以及扩展方法的名称不正确。在项目中使用的一个库中,有一个列表的扩展方法,称为“ FirstOrDefult”。显然,就我而言,此方法始终返回第一个元素。包括LINQ名称空间就可以解决问题,现在一切都按预期运行