从'System.Collections.Generic.IList <double>'到'System.Collections.IList'</double>没有隐式引用转换

时间:2014-01-15 15:16:20

标签: c# .net generics

我正在尝试构建一个方法来检查列表是否为空:

    public static T1 NotEmpty<T1>(T1 argument, string message = null) where T1 : class, IEnumerable
    {
        if (argument == null)
        {
            throw new ArgumentNullException(message);
        }
        if(!argument.Any())
        {
            throw new ArgumentException(message);
        }
        return argument;
    }

并像这样使用它:

public void MyMethod(IList<double> stuff)
{
    _stuff = NotEmpty(stuff);
    ....
}

但它没有编译。扩展方法Any()似乎仅在IEnumerable的通用版本上定义。但是,我无法定义NotEmpty方法,使泛型参数实现IEnumerable的通用版本,编译器能够自动计算类型。我想要的最后一件事是手动输入所有类型。

是否有可能以比下面给出的更优雅的方式实现它?

    public static T1 NotEmpty<T1>(T1 argument, string message = null) where T1 : class, IEnumerable
    {
        if (argument == null)
        {
            throw new ArgumentNullException(message);
        }
        if(!argument.GetEnumerator().MoveNext())
        {
            throw new ArgumentException(message);
        }
        return argument;
    }

3 个答案:

答案 0 :(得分:6)

只需添加.OfType<Object>()即可将非通用IEnumerable变为更有用的内容:

public static T1 NotEmpty<T1>(T1 argument, string message = null) where T1 : class, IEnumerable
{
    if (argument == null)
        throw new ArgumentNullException(message);

    if(!argument.OfType<Object>().Any())
        throw new ArgumentException(message);

    return argument;
}

答案 1 :(得分:6)

您可以Cast它,以便您可以使用LINQ扩展方法。

CastIEnumerable的扩展方法,而大多数其他LINQ扩展方法(例如Any)仅适用于IEnumerable<T>。由于使用IEnumerable<T>会使代码复杂化(由于涉及两种泛型类型),我可能会这样做:

public static T1 NotEmpty<T1>(T1 argument, string message = null) where T1 : class, IEnumerable
{
    if (argument == null)
    {
        throw new ArgumentNullException(message);
    }
    if(!argument.Cast<object>().Any())
    {
        throw new ArgumentException(message);
    }
    return argument;
}

答案 2 :(得分:-1)

为什么使用Enumerable作为泛型类型?这是关于Enumerable的类型:

public static IEnumerable<T1> NotEmpty<T1>(IEnumerable<T1> argument, string message = null) where T1 : class
        {
            if (argument == null)
            {
                throw new ArgumentNullException(message);
            }
            if(!argument.Any())
            {
                throw new ArgumentException(message);
            }
            return argument;
        }