【问题标题】:ICollection / ICollection<T> ambiguity problemICollection / ICollection<T> 歧义问题
【发布时间】:2010-12-05 09:27:36
【问题描述】:

只想为syntactic 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)'

这个问题有什么规范的解决方案吗?

不,我不想在调用此方法之前执行强制转换;)

【问题讨论】:

  • 你能举出一个有这个问题的集合,以便我们验证我们的答案吗?
  • 你确定这些是声明吗?错误消息似乎表明它是 IList 而不是 ICollection。
  • 第二种方法还有必要吗?
  • 这在使用接口时特别需要(当您不知道正在使用的实例的具体类型时):ICollection 不实现 ICollection...
  • @Jon Skeet:这是因为List&lt;T&gt; 实现了ICollection 和IList&lt;T&gt;,而IList&lt;T&gt; 继承了ICollection&lt;T&gt;。所以List&lt;T&gt; 实现了ICollection 和ICollection&lt;T&gt;。

标签: c# extension-methods icollection ambiguous


【解决方案1】:

我解决歧义的最佳方法:为所有常见的非泛型 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&lt;T&gt; 上工作,因为 Count() 是一种在使用 Linq-to-Entity 或 Linq-to-SQL 时可以触发数据库请求的方法。

【讨论】:

  • 使用几周后,它绝对是最好的解决方案,我们在这里大量采用。
【解决方案2】:

这是因为有些集合实现了这两个接口,你应该像这样将集合转换为具体的接口

((ICollection)myList).IsNotEmpty();

或者

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

是的,如果 obj == null,您将得到 NullReferanceException,因此您可以删除 null 检查;)这意味着您的扩展方法只是将 Count 与 0 进行比较,您可以在没有扩展方法的情况下执行此操作;)

【讨论】:

  • 所有的泛型版本都实现了它们的非泛型版本,因此任何泛型类都将兼有。
  • 就像我在问题的最后一句中所说的那样,我不想在通话前进行演员表。这是针对 SYNTACTIC SUGAR 的,如果我需要添加演员表,那么它绝对没用:p 我的问题仍然存在:有什么方法可以解决所有系列的歧义?
  • @ArsenMkrt:扩展方法可以在value == null的变量上调用,不会发生异常
  • @Rex M:您的意思是 .NET Framework 中的所有泛型类都实现了非泛型接口吗?有文档链接吗?
猜你喜欢
  • 2010-12-05
  • 2011-01-09
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
  • 2012-05-22
  • 1970-01-01
  • 2012-02-03
相关资源
最近更新 更多