通常情况下,如果您只想检查IEnumerable<T>
中是否有任何项目,请使用.Any()
而不是.count > 0
- 尤其是当你遇到像LINQ-To这样的内容时-Entities和.count
可能会有严重的性能损失。
我遇到的问题是我正在编写IValueConverter
来更改对象的可见性,具体取决于枚举是否包含项目:
public class CollectionEmptyVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var col = value as ICollection;
if (col == null) { return Visibility.Collapsed.ToString(); }
return (col.Count > 0) ? Visibility.Visible.ToString() : Visibility.Collapsed.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
因此,在这种情况下,我无法在IEnumerable<T>
上使用常规扩展方法,因为此时我无法使用<T>
。我当前的实现限制了我实现ICollection
的事情,这可能并不总是可取的。
我怎样才能以更有效的方式做到这一点?裸露的IEnumerable
(无<T>
)没有.Any()
。
答案 0 :(得分:3)
这样可以正常工作:
public static class ExtensionMethods
{
public static bool Any(this IEnumerable t) {
foreach (var o in t)
return true;
return false;
}
}
基准:
public static class ExtensionMethods
{
public static bool AnyJR(this IEnumerable t)
{
foreach (var o in t)
return true;
return false;
}
public static bool AnyPhonicUK(this IEnumerable t)
{
var e = t.GetEnumerator();
try {
return e.MoveNext();
}
finally {
var edisp = e as IDisposable;
if (edisp != null)
edisp.Dispose();
}
}
}
class Program
{
static long Test_AnyJR(List<int> l, int n)
{
var sw = Stopwatch.StartNew();
for (int i = 0; i < n; i++) {
bool any = l.AnyJR();
}
sw.Stop();
return sw.ElapsedMilliseconds;
}
static long Test_AnyPhonicUK(List<int> l, int n)
{
var sw = Stopwatch.StartNew();
for (int i = 0; i < n; i++) {
bool any = l.AnyPhonicUK();
}
sw.Stop();
return sw.ElapsedMilliseconds;
}
static void Main(string[] args)
{
var list = new List<int> { 1, 2, 3, 4 };
int N = 10000000;
Console.WriteLine("{0} iterations using AnyJR took {1} ms.", N, Test_AnyJR(list, N));
Console.WriteLine("{0} iterations using AnyPhonicUK took {1} ms.", N, Test_AnyPhonicUK(list, N));
Console.ReadLine();
}
}
结果:
10000000 iterations using AnyJR took 484 ms.
10000000 iterations using AnyPhonicUK took 393 ms.
答案 1 :(得分:0)
public object Convert(object value, Type targetType, object parameter, string language)
{
var col = value as ICollection;
if (col != null)
return col.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
var enu = (IEnumerable)value;
foreach (var obj in enu)
return true;
return false;
}
或者(更简洁,但可能是头发更慢):
public object Convert(object value, Type targetType, object parameter, string language)
{
var enu = (IEnumerable)value;
return enu.Cast<object>().Any() ? Visibility.Visible : Visibility.Collapsed;
}