You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写返回原类型的IReadOnlyCollection扩展方法遇类型推断问题求解

解决方法

你可以通过两种方式避免需要显式指定两个泛型参数:

方法1:利用非泛型ICollection约束(适用于大多数常见集合类型)

如果你的集合类型都实现了非泛型ICollection接口(比如数组、List<T>、HashSet<T>等),可以将扩展方法的泛型约束改为仅针对ICollection,这样编译器就能自动推断出类型参数:

public static T ThrowIfNullOrEmpty<T>(this T? collection, [CallerArgumentExpression("collection")] string? paramName = null)
    where T : class, ICollection
{
    if (collection is null || collection.Count == 0)
    {
        throw new ArgumentException($"{paramName} is null or empty", paramName);
    }

    return collection;
}

这样调用parameters.ThrowIfNullOrEmpty()时,编译器会自动推断T为MyType[],无需额外指定泛型参数。

方法2:模式匹配兼容所有只读集合与可枚举类型

如果需要支持仅实现IReadOnlyCollection<T>而未实现非泛型ICollection的自定义集合,可以使用模式匹配来检测任意IReadOnlyCollection<>实现,同时兼容普通IEnumerable类型:

public static T ThrowIfNullOrEmpty<T>(this T? collection, [CallerArgumentExpression("collection")] string? paramName = null)
    where T : notnull
{
    if (collection is null)
    {
        throw new ArgumentNullException(paramName);
    }

    // 优先检查IReadOnlyCollection<T>(任意元素类型)
    if (collection is IReadOnlyCollection<object> readOnlyCollection)
    {
        if (readOnlyCollection.Count == 0)
        {
            throw new ArgumentException($"{paramName} is empty", paramName);
        }
    }
    // 检查非泛型ICollection
    else if (collection is ICollection nonGenericCollection)
    {
        if (nonGenericCollection.Count == 0)
        {
            throw new ArgumentException($"{paramName} is empty", paramName);
        }
    }
    // 最后通过枚举判断空集合
    else
    {
        using var enumerator = collection.GetEnumerator();
        if (!enumerator.MoveNext())
        {
            throw new ArgumentException($"{paramName} is empty", paramName);
        }
    }

    return collection;
}

原代码问题解析

你最初的代码需要两个泛型参数<T, V>,但编译器无法自动推断V的类型——虽然T实现了IReadOnlyCollection<V>,但C#的类型推断无法从T反向推导出V(除非在C# 10+的某些场景下)。通过上述两种方式,我们可以避开显式指定V的需求,让方法更易用。

内容的提问来源于stack exchange,提问作者JHBonarius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 19:30:48