ICollection / ICollection <T>проблема неоднозначности - PullRequest
4 голосов
/ 09 октября 2009

Просто хочу сделать простое расширение для синтаксического sygar :

public static bool IsNotEmpty(this ICollection obj)
{
    return ((obj != null)
        && (obj.Count > 0));
}

public static bool IsNotEmpty<T>(this ICollection<T> obj)
{
    return ((obj != null)
        && (obj.Count > 0));
}

Отлично работает, когда я работаю с некоторыми коллекциями, но при работе с другими я получаю

Звонок между следующие методы или свойства: 'PowerOn.ExtensionsBasic.IsNotEmpty (System.Collections.IList)' а также 'PowerOn.ExtensionsBasic.IsNotEmpty (System.Collections.Generic.ICollection)'

Есть ли каноническое решение этой проблемы?

Нет, я не хочу выполнять приведение перед вызовом этого метода;)

Ответы [ 2 ]

4 голосов
/ 12 октября 2009

Мой лучший способ устранить неоднозначность: определить перегрузку для всех распространенных неуниверсальных классов ICollection. Это означает, что пользовательская коллекция ICollection не будет совместима, но это не так уж и сложно, поскольку генерики становятся нормой.

Вот весь код:

/// <summary>
/// Check the given array is empty or not
/// </summary>
public static bool IsNotEmpty(this Array obj)
{
    return ((obj != null)
        && (obj.Length > 0));
}
/// <summary>
/// Check the given ArrayList is empty or not
/// </summary>
public static bool IsNotEmpty(this ArrayList obj)
{
    return ((obj != null)
        && (obj.Count > 0));
}
/// <summary>
/// Check the given BitArray is empty or not
/// </summary>
public static bool IsNotEmpty(this BitArray obj)
{
    return ((obj != null)
        && (obj.Count > 0));
}
/// <summary>
/// Check the given CollectionBase is empty or not
/// </summary>
public static bool IsNotEmpty(this CollectionBase obj)
{
    return ((obj != null)
        && (obj.Count > 0));
}
/// <summary>
/// Check the given DictionaryBase is empty or not
/// </summary>
public static bool IsNotEmpty(this DictionaryBase obj)
{
    return ((obj != null)
        && (obj.Count > 0));
}
/// <summary>
/// Check the given Hashtable is empty or not
/// </summary>
public static bool IsNotEmpty(this Hashtable obj)
{
    return ((obj != null)
        && (obj.Count > 0));
}
/// <summary>
/// Check the given Queue is empty or not
/// </summary>
public static bool IsNotEmpty(this Queue obj)
{
    return ((obj != null)
        && (obj.Count > 0));
}
/// <summary>
/// Check the given ReadOnlyCollectionBase is empty or not
/// </summary>
public static bool IsNotEmpty(this ReadOnlyCollectionBase obj)
{
    return ((obj != null)
        && (obj.Count > 0));
}
/// <summary>
/// Check the given SortedList is empty or not
/// </summary>
public static bool IsNotEmpty(this SortedList obj)
{
    return ((obj != null)
        && (obj.Count > 0));
}
/// <summary>
/// Check the given Stack is empty or not
/// </summary>
public static bool IsNotEmpty(this Stack obj)
{
    return ((obj != null)
        && (obj.Count > 0));
}
/// <summary>
/// Check the given generic is empty or not
/// </summary>
public static bool IsNotEmpty<T>(this ICollection<T> obj)
{
    return ((obj != null)
        && (obj.Count > 0));
}

Обратите внимание, что я не хотел, чтобы он работал на IEnumerable<T>, потому что Count() - это метод, который может инициировать запрос к базе данных, если вы работаете с Linq-to-Entity или Linq-to-SQL.

4 голосов
/ 09 октября 2009

Это потому, что некоторые коллекции реализуют оба интерфейса, вы должны преобразовать коллекцию в конкретный интерфейс, как это

((ICollection)myList).IsNotEmpty();

Или

((ICollection<int>)myIntList).IsNotEmpty();

И да, вы получите NullReferanceException, если obj == null, так что вы можете удалить проверку null;), что означает, что ваш метод расширения просто сравнивает Count с 0, который вы можете сделать без метода расширения;)

...