当面试官面对C#中关于LINQ和Lambda表达式的面试题时,通常会涉及这两个主题的基本概念、用法、实际应用以及与其他相关技术的对比等。以下是一些可能的面试题目,附带简要解答和相关案例和代码:
解答:延迟执行是指LINQ查询在遍历结果之前不会立即执行,而是在实际需要时才会执行查询。立即执行是指LINQ查询会立即执行,返回实际结果。在LINQ中,使用deferred
关键字可以区分两者。
案例和代码:假设有一个数据源numbers
,我们通过Where
筛选出大于10的元素,然后通过Select
将它们投影为新的集合。Where
是延迟执行的,而Select
是立即执行的:
var numbers = new List<int> { 5, 12, 8, 15, 3 };
var filteredNumbers = numbers.Where(n => n > 10); // 延迟执行
// 此时并未执行查询
var selectedNumbers = filteredNumbers.Select(n => n * 2); // 立即执行
// 现在执行查询
foreach (var number in selectedNumbers)
{
Console.WriteLine(number);
}
解答:FirstOrDefault
用于返回序列中的第一个元素,如果序列为空,则返回默认值。SingleOrDefault
用于返回序列中的唯一一个元素,如果序列为空或有多个元素,则抛出异常。
案例和代码:假设有一个包含员工信息的Employee
类的集合。我们可以使用FirstOrDefault
获取第一个员工和SingleOrDefault
获取指定ID的员工:
class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
}
List<Employee> employees = new List<Employee>
{
new Employee { EmployeeId = 1, Name = "John" },
new Employee { EmployeeId = 2, Name = "Alice" },
new Employee { EmployeeId = 3, Name = "Bob" }
};
var firstEmployee = employees.FirstOrDefault();
var employeeWithId2 = employees.SingleOrDefault(e => e.EmployeeId == 2);
var employeeWithId4 = employees.SingleOrDefault(e => e.EmployeeId == 4); // 返回null
var employeeWithId1 = employees.SingleOrDefault(e => e.EmployeeId == 1); // 抛出异常,因为有多个ID为1的员工
解答:GroupBy
方法用于根据指定的键对集合中的元素进行分组。它将相同键的元素分为一组,并返回一个包含分组结果的集合。
案例和代码:假设有一个包含产品信息的Product
类的集合,我们可以根据产品类别进行分组:
class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public string Category { get; set; }
}
List<Product> products = new List<Product>
{
new Product { ProductId = 1, Name = "Product A", Category = "Category 1" },
new Product { ProductId = 2, Name = "Product B", Category = "Category 2" },
new Product { ProductId = 3, Name = "Product C", Category = "Category 1" },
new Product { ProductId = 4, Name = "Product D", Category = "Category 3" },
};
var groupedProducts = products.GroupBy(p => p.Category);
foreach (var group in groupedProducts)
{
Console.WriteLine($"Category: {group.Key}");
foreach (var product in group)
{
Console.WriteLine($"Product ID: {product.ProductId}, Name: {product.Name}");
}
}
解答:可以使用Join
方法在两个不同的集合之间执行连接查询。Join
方法接受两个集合、一个键选择器和一个结果选择器,并返回连接的结果。
案例和代码:假设有两个包含订单信息的集合orders
和customers
,我们可以根据CustomerId
进行连接查询:
class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; }
}
class Order
{
public int OrderId { get; set; }
public int CustomerId { get; set; }
public decimal Amount { get; set; }
}
List<Customer> customers = new List<Customer>
{
new Customer { CustomerId = 1, Name = "John" },
new Customer { CustomerId = 2, Name = "Alice" },
new Customer { CustomerId = 3, Name = "Bob" }
};
List<Order> orders = new List<Order>
{
new Order { OrderId = 1, CustomerId = 1, Amount = 100.00m },
new Order { OrderId = 2, CustomerId = 2, Amount = 50.00m },
new Order { OrderId = 3, CustomerId = 1, Amount = 200.00m },
new Order { OrderId = 4, CustomerId = 3, Amount = 80.00m }
};
var orderDetails = orders
.Join(customers,
order => order.CustomerId,
customer => customer.CustomerId,
(order, customer) => new
{
OrderId = order.OrderId,
CustomerName = customer.Name,
Amount = order.Amount
});
foreach (var order in orderDetails)
{
Console.WriteLine($"Order ID: {order.OrderId}, Customer: {order.CustomerName}, Amount: {order.Amount:C}");
}
解答:操作符重载是指对C#中的运算符进行自定义实现,使得自定义
类可以像内置类型一样使用运算符。在LINQ中,可以通过实现IEnumerable
接口和IEnumerator
接口来对自定义类启用LINQ查询。
案例和代码:假设有一个自定义的`Vector`类表示二维向量,我们可以实现`IEnumerable<T>`接口来启用LINQ查询:
```csharp
class Vector
{
public double X { get; set; }
public double Y { get; set; }
public Vector(double x, double y)
{
X = x;
Y = y;
}
}
// 实现IEnumerable接口
class VectorCollection : IEnumerable<Vector>
{
private List<Vector> vectors = new List<Vector>();
public void Add(Vector vector)
{
vectors.Add(vector);
}
public IEnumerator<Vector> GetEnumerator()
{
return vectors.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
// 使用自定义的VectorCollection进行LINQ查询
VectorCollection vectorCollection = new VectorCollection
{
new Vector(1, 2),
new Vector(2, 3),
new Vector(3, 4)
};
var sumVector = vectorCollection.Aggregate((v1, v2) => new Vector(v1.X + v2.X, v1.Y + v2.Y));
Console.WriteLine($"Sum Vector: X={sumVector.X}, Y={sumVector.Y}");
```
以上是另外五个关于C#中LINQ和Lambda表达式的优质面试题目,希望这些问题和示例代码能够帮助您更好地理解和掌握LINQ和Lambda表达式的使用。在面试时,通过回答这些问题并展示相应的代码,您可以展现出对LINQ和Lambda表达式的深刻理解和熟练应用能力。祝您面试顺利!