简体   繁体   English

我的Lambda表达有什么问题?

[英]What's Wrong With My Lambda Expression?

I'm trying to write a simple Lambda expression in C#: 我正在尝试在C#中编写一个简单的Lambda表达式:

int numElements = 3;
string[]firstnames = {"Dave", "Jim", "Rob"};
string[]lastnames = {"Davidson", "Jameson", "Robertson"};

List<Person> people = new List<Person>();

for(int i = 0 ; i < numElements; i++)
{
    people.Add(new Person { FirstName = firstnames[i], LastName = lastnames[i] });                
}

bool test = people.Contains(p => p.FirstName == "Bob");

My understanding of Lambda expressions and how they work is still a little shady and I miffed as to why this will not work...I'm trying to find out if a list contains a name... 我对Lambda表达式及其工作方式的理解还有些阴暗,我想知道为什么它不起作用...我试图找出列表中是否包含名称...

Are you looking for: 您是否在寻找:

bool test = people.Any(p => p.FirstName == "Bob");

Or are you mixing Rob and Bob? 还是您要混合Rob和Bob?

The problem here is not lambdas but instead the boundaries of the for loop. 这里的问题不是lambda,而是for循环的边界。 The arrays you defined have a length of 3 but numElements is defined to have a value of 10 . 您定义的数组的长度为3,但是numElements的值定义为10 This means you will get an exception for an illegal array index on the 4th iteration of the loop. 这意味着您将在循环的第4次迭代中获得非法数组索引的异常。 Try the following 尝试以下

int numElements = 3;

Or more simply remove the numElements variable and instead iterate to the length of the firstnames array 或更简单地删除numElements变量,而是迭代到firstnames数组的长度

for (int i = 0; i < firstnames.length; i++) {
  ...
}

EDIT 编辑

OP indicated that the numElements originally posted was a typo. OP表示最初发布的numElements是一个错字。 Other possible sources of error in the code 代码中其他可能的错误源

  • Use "Rob" instead of "Bob" if you want to find a matching element 如果要查找匹配的元素,请使用"Rob"而不是"Bob"
  • The Contains method on GenericList<T> needs to have a compatible delegate signature. GenericList<T>上的Contains方法需要具有兼容的委托签名。 Func<T, bool> for example Func<T, bool>
  1. Make sure you are linking the System.Linq namemespace, ie 确保您链接了System.Linq名称空间,即

     using System.Linq; 
  2. You are using the Contains method. 您正在使用Contains方法。 This method expects a Person and will use an equality comparison to determine if your collection already contains it. 此方法需要一个Person并将使用相等比较来确定您的集合是否已包含它。 In the default case, the equality comparison defaults to reference comparison so it will never contain it, but that's another topic. 在默认情况下,相等比较默认为引用比较,因此它永远不会包含引用比较,但这是另一个主题。

  3. To achieve your goal, use the Any method. 为了实现您的目标,请使用Any方法。 This will tell you if ANY of the elements in your collection conform to a condition. 这将告诉您集合中的任何元素是否符合条件。

     people.Any(p => p.FirstName == "BoB"); 

You may want to read about the extension methods First and FirstOrDefault and Where as they would also solve your problem. 您可能需要阅读有关扩展方法 First和FirstOrDefault的信息,以及它们在哪里也可以解决您的问题的信息。

You don't set numElements to the correct value ( you set it to 10, but your arrays only have 3 values) - furthermore you don't even need it, just use a collection initializer instead of those separate string arrays: 您没有将numElements设置为正确的值(将其设置为10,但是您的数组只有3个值)-此外,您甚至不需要它,只需使用集合初始值设定项而不是这些单独的字符串数组即可:

GenericList<Person> people = new GenericList<Person>()
{
    new Person { FirstName = "Dave", LastName = "Davidson" },
    new Person { FirstName = "Jim", LastName = "Jameson" }
    new Person { FirstName = "Rob", LastName = "Robertson" }
}

Now assuming your GenericList<T> class implements IEnumerable<T> you can use Any() to do your test: 现在,假设您的GenericList<T>类实现IEnumerable<T> ,则可以使用Any()进行测试:

bool test = people.Any(p => p.FirstName == "Bob");

what your real problem with this lambdas ? 您对此lambda的真正问题是什么?

If because you have test false then that's true you don't have "Bob" in firstName 如果因为测试错误而成立,那么您的名字中没有“鲍勃”

bool test = people.Contains(p => p.FirstName == "Bob");

and

string[]firstnames = {"Dave", "Jim", "Rob"};

Couple of problems here. 这里有几个问题。

One: GenericList is not a type. 一个: GenericList不是类型。 You were probably looking for the generic type System.Collections.Generic.List<T> . 您可能正在寻找通用类型System.Collections.Generic.List<T>

Two: Contains accepts a Person in your example, not a delegate (lambdas are a new way to write delegates as of C# 3). 二:在您的示例中, Contains接受一个Person ,而不是一个委托(lambda是从C#3开始编写委托的一种新方法)。 One way to get what you want here would be to combine Where and Count , in the form of bool test = people.Where(p => p.FirstName == "Bob").Count() > 0; 一种获得所需结果的方法是将WhereCount结合起来,以bool test = people.Where(p => p.FirstName == "Bob").Count() > 0;

// We will use these things:
Predicate<Person> yourPredicate = p => p.FirstName == "Bob";
Func<Person, bool> yourPredicateFunction = p => p.FirstName == "Bob";
Person specificPerson = people[0];

// Checking existence of someone:
bool test = people.Contains(specificPerson);
bool anyBobExistsHere = people.Exists(yourPredicate);

// Accessing to a person/people:
IEnumerable<Person> allBobs = people.Where(yourPredicateFunction);
Person firstBob = people.Find(yourPredicate);
Person lastBob = people.FindLast(yourPredicate);

// Finding index of a person
int indexOfFirstBob = people.FindIndex(yourPredicate);
int indexOfLastBob = people.FindLastIndex(yourPredicate);

You should play with LINQ methods somewhile... 您应该在一段时间内使用LINQ方法...

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

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