C# 利用带有自定义可枚举扩展的PLINQ

C# 利用带有自定义可枚举扩展的PLINQ,c#,linq,plinq,C#,Linq,Plinq,许多自定义可枚举扩展可以通过其他内置操作来实现-例如,这种简单方便的方法: public static bool AnyOf<TElement>(this TElement item, IEnumerable<TElement> items) { return items.Any(a => EqualityComparer<TElement>.Default.Equals(a, item)); } 我得出的结论是,如果不为每个方法创建一个具有不

许多自定义可枚举扩展可以通过其他内置操作来实现-例如,这种简单方便的方法:

public static bool AnyOf<TElement>(this TElement item, IEnumerable<TElement> items)
{
    return items.Any(a => EqualityComparer<TElement>.Default.Equals(a, item));
}
我得出的结论是,如果不为每个方法创建一个具有不同签名的副本,这是不可能的,但也许我遗漏了一些东西。(哎呀,总是有不可能的问题!)


也许一个更好的例子是这样的,它可以从并行化中获益(显然可以链接,等等)

public static IEnumerable<string> ToStrings(this IEnumerable<object> ienum)
{
    return ienum.Select(a=> a.ToString());
}
公共静态IEnumerable to字符串(此IEnumerable ienum)
{
返回ienum.Select(a=>a.ToString());
}

^编译器错误:

 The type 'ParallelQuery<TElement>' cannot be used as type parameter
 'TEnumerable' in the generic type or method
 'AnyOf<TElement,TEnumerable>(TElement, TEnumerable)'. There is no
 implicit reference conversion from 'ParallelQuery<TElement>' to
 'IEnumerable<TElement>'
类型“ParallelQuery”不能用作类型参数
泛型类型或方法中的“TEnumerable”
'任何一个(远程通信,可数)'。没有
从“ParallelQuery”到的隐式引用转换
“IEnumerable”


同样值得考虑的是,并非所有的ParallelQuery/Enumerable方法都是等效的,即使它们是编译的。

我在编写IQueryable/IEnumerable扩展时也做过类似的工作。试图找出公共位涉及声明包含表达式的静态变量,然后从函数的两个不同版本引用该表达式。我已经没有代码了,当我完成时,它非常难看,我对它不满意。这里有一个简单的例子

Expression<Func<PersonHistory, bool>> IsCurrent = (p) => p.Ends > DateTime.Now && p.Starts <= DateTime.Now;

//Then in each Extension method:
var query = db.PersonHistories.Where(IsCurrent);

Expression IsCurrent=(p)=>p.Ends>DateTime.Now&&p.start您可以通过在方法内部使用选中的强制转换(即运行时切换)来完成此操作,如下所示:

public static bool AnyOf(此远程通讯项,IEnumerable项)
{
var parallelItems=作为ParallelQuery的项
if(parallelItems!=null)
{
返回parallelItems.Any(a=>EqualityComparer.Default.Equals(a,item))
}
//其他运行时检查
....
//else返回默认的IEnumerable实现
returnitems.Any(a=>EqualityComparer.Default.Equals(a,item));
}

实际问题是什么?嗯,呃。有点激动:“有没有办法编写一个LINQ扩展,它也可以与PLINQ一起使用?”。你所有的扩展方法都这么短吗?你有多少?这有什么帮助?Is仍然意味着您有两次相同的代码。@svick ala
我得出结论,如果不创建每个方法的副本并使用不同的签名,这是不可能的,但是可能我遗漏了一些东西
&
“有没有办法编写一个同样适用于PLINQ的LINQ扩展?”
他的实际问题不是写两次,而是有一个单独的签名,这将取决于枚举行为,这是一个解决方案,但我相信这样做的根本原因是避免代码重复。
 The type 'ParallelQuery<TElement>' cannot be used as type parameter
 'TEnumerable' in the generic type or method
 'AnyOf<TElement,TEnumerable>(TElement, TEnumerable)'. There is no
 implicit reference conversion from 'ParallelQuery<TElement>' to
 'IEnumerable<TElement>'
Expression<Func<PersonHistory, bool>> IsCurrent = (p) => p.Ends > DateTime.Now && p.Starts <= DateTime.Now;

//Then in each Extension method:
var query = db.PersonHistories.Where(IsCurrent);
public static bool AnyOf<TElement>(this TElement item, IEnumerable<TElement> items)
{
    var parallelItems = items as ParallelQuery<TElement>
    if(parallelItems != null)
    {
         return parallelItems.Any(a => EqualityComparer<TElement>.Default.Equals(a, item))
    }
    //other runtime checks
    ....
    //else return default IEnumerable implementation
    return items.Any(a => EqualityComparer<TElement>.Default.Equals(a, item));
}