0

因此,通常如果您想简单地检查是否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();
    }
}

所以在这种情况下,我不能在 an 上使用正常的扩展方法,IEnumerable<T>因为此时我不能拥有 a <T>。我目前的实现将我限制在那些ICollection可能并不总是理想的实现上。

我怎样才能以更有效的方式做到这一点?裸露的IEnumerable(sans <T>) 没有.Any().

4

2 回答 2

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.
于 2013-08-03T23:42:02.310 回答
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;
}
于 2013-08-03T23:56:09.163 回答