C# 匿名方法的问题
我有一个方法,除了一个C# 匿名方法的问题,c#,linq-to-sql,lambda,anonymous-types,C#,Linq To Sql,Lambda,Anonymous Types,我有一个方法,除了一个IEnumerable和一个lambda表达式之外,它描述了用于将linq to sql集合与数组进行比较的字段。该方法返回匹配的记录 public IEnumerable<ZipCode> match<T>(IEnumerable<T> values, Func<ZipCode, T> matchPhrase) { return (from zipCode in _table
IEnumerable
和一个lambda表达式之外,它描述了用于将linq to sql集合与数组进行比较的字段。该方法返回匹配的记录
public IEnumerable<ZipCode> match<T>(IEnumerable<T> values,
Func<ZipCode, T> matchPhrase) {
return (from zipCode in _table
where values.Contains<T>(matchPhrase)
select zipCode).Distinct();
}
更新
根据John关于使用HashSet的建议,我已经更改了我的代码,但是现在我得到了一个不同的错误
方法“System.Object DynamicInvoke(System.Object[])”不支持转换为SQL
我想我可能对我的问题不是很清楚,我想我使用了错误的方法签名来获得我想要的结果。让我用一个更简单的代码示例来解释:
public IEnumerable<ZipCode> match(IEnumerable<string> values) {
return (from zipCode in _table
where values.Contains(zipCode.zipcode)
select zipCode).Distinct();
}
公共IEnumerable匹配(IEnumerable值){
返回(来自_表中的zipCode)
其中values.Contains(zipCode.zipCode)
选择zipCode).Distinct();
}
我正在努力完成这项任务,但是使用匿名类型。我想通过lambda传入要在Contains()
中使用的字段。因此,zipCode.zipCode
将作为第二个参数传递到方法中:x=>x.zipCode
您忘记了(zipCode)
中的包含
public IEnumerable<ZipCode> match<T>(IEnumerable<T> values, Func<ZipCode, T> matchPhrase) {
return (from zipCode in _table
where values.Contains(matchPhrase(zipCode)) // <- Here (and you don't need to specify <T>, the compiler deduce it from the argument)
select zipCode).Distinct();
}
您忘记了(zipCode)
中的包含
public IEnumerable<ZipCode> match<T>(IEnumerable<T> values, Func<ZipCode, T> matchPhrase) {
return (from zipCode in _table
where values.Contains(matchPhrase(zipCode)) // <- Here (and you don't need to specify <T>, the compiler deduce it from the argument)
select zipCode).Distinct();
}
我怀疑你想给代表打电话:
return (from zipCode in _table
where values.Contains(matchPhrase(zipCode))
select zipCode).Distinct();
请注意,这可能会非常昂贵。您可能需要先创建一个集合:
HashSet<T> valueSet = new HashSet<T>(values);
return _table.Where(x => valueSet.Contains(matchPhrase(x))
.Distinct();
HashSet-valueSet=新的HashSet(值);
return _table.Where(x=>valueSet.Contains(匹配短语(x))
.Distinct();
(我在这里删除了查询表达式,因为它在可读性方面弊大于利。)我怀疑您想调用该委托:
return (from zipCode in _table
where values.Contains(matchPhrase(zipCode))
select zipCode).Distinct();
请注意,这可能会非常昂贵。您可能需要先创建一个集合:
HashSet<T> valueSet = new HashSet<T>(values);
return _table.Where(x => valueSet.Contains(matchPhrase(x))
.Distinct();
HashSet-valueSet=新的HashSet(值);
return _table.Where(x=>valueSet.Contains(匹配短语(x))
.Distinct();
(我在这里删除了查询表达式,因为它在可读性方面弊大于利。)包含只接受字符串作为参数,而不接受表达式。您将无法在此级别对其进行参数化
您可以将整个where部分作为参数传入:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var values = new List<string>();
values.Add("123");
Console.WriteLine(
Match(zip => values.Contains(zip.Code)).Count()); // -> 1
Console.WriteLine(
Match(zip => values.Contains(zip.OtherCode)).Count()); // -> 0
Console.Read();
}
public static IEnumerable<ZipCode> Match(Expression<Func<ZipCode, bool>> predicate)
{
var table = new List<ZipCode>
{ new ZipCode { Code = "123" }, new ZipCode { OtherCode = "234" } }
.AsQueryable();
return (from zipCode in table.Where(predicate)
select zipCode).Distinct();
}
}
public class ZipCode
{
public string Code { get; set; }
public string OtherCode { get; set; }
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Linq.Expressions;
命名空间控制台应用程序
{
班级计划
{
静态void Main(字符串[]参数)
{
var值=新列表();
价值。添加(“123”);
控制台写入线(
匹配(zip=>values.Contains(zip.Code)).Count();//->1
控制台写入线(
匹配(zip=>values.Contains(zip.OtherCode)).Count();//->0
Console.Read();
}
公共静态IEnumerable匹配(表达式谓词)
{
var table=新列表
{new ZipCode{Code=“123”},new ZipCode{OtherCode=“234”}
.AsQueryable();
返回(来自表中的zipCode.Where(谓词)
选择zipCode).Distinct();
}
}
公共类ZipCode
{
公共字符串代码{get;set;}
公共字符串OtherCode{get;set;}
}
}
Contains只接受字符串作为参数,不接受表达式。您将无法在此级别对其进行参数化
您可以将整个where部分作为参数传入:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var values = new List<string>();
values.Add("123");
Console.WriteLine(
Match(zip => values.Contains(zip.Code)).Count()); // -> 1
Console.WriteLine(
Match(zip => values.Contains(zip.OtherCode)).Count()); // -> 0
Console.Read();
}
public static IEnumerable<ZipCode> Match(Expression<Func<ZipCode, bool>> predicate)
{
var table = new List<ZipCode>
{ new ZipCode { Code = "123" }, new ZipCode { OtherCode = "234" } }
.AsQueryable();
return (from zipCode in table.Where(predicate)
select zipCode).Distinct();
}
}
public class ZipCode
{
public string Code { get; set; }
public string OtherCode { get; set; }
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Linq.Expressions;
命名空间控制台应用程序
{
班级计划
{
静态void Main(字符串[]参数)
{
var值=新列表();
价值。添加(“123”);
控制台写入线(
匹配(zip=>values.Contains(zip.Code)).Count();//->1
控制台写入线(
匹配(zip=>values.Contains(zip.OtherCode)).Count();//->0
Console.Read();
}
公共静态IEnumerable匹配(表达式谓词)
{
var table=新列表
{new ZipCode{Code=“123”},new ZipCode{OtherCode=“234”}
.AsQueryable();
返回(来自表中的zipCode.Where(谓词)
选择zipCode).Distinct();
}
}
公共类ZipCode
{
公共字符串代码{get;set;}
公共字符串OtherCode{get;set;}
}
}
match
是一个函数,而contains根本不接受函数。@bflemi3查看方法的联接“版本”。它将复杂性从O(n^2)降低到O(n)。match
是一个函数,contains根本不接受函数。@bflemi3查看联接“版本”它将复杂性从O(n^2)降低到O(n)。您几乎肯定希望在一开始就将值
放入散列集
,以便更有效地搜索它。实际上,您正在枚举值
,对\u表
中的每个项进行线性搜索。这既非常低效,也会多次迭代可枚举项,这确实非常有用在这样的函数中应该避免。几乎可以肯定的是,您希望在一开始就将值
放入哈希集
,以便更有效地搜索它。因为您正在枚举值
,对\u表
中的每个项进行线性搜索。这既非常低效,又会迭代多次可枚举,在这样的函数中确实应该避免这种情况。@bflemi3我想建议您不要将函数的参数命名为与方法本身相同的名称……这可能会引起混淆。@JonSkeet为什么要使用哈希集,然后使用Where和Contains,而LINQ join方法可以以更高效的方式完美地完成此任务?@C艾德里克比农:是什么让你认为加入比p更重要