繁体   English   中英

无法返回IEnumerable <TEnum> 代替IEnumerable <T>

[英]Unable to return IEnumerable<TEnum> in place of IEnumerable<T>

我写了这个EnumHelper方法

    public static IEnumerable<T> AsEnumerable<TEnum, T>(Func<TEnum, T> projection = null) where TEnum : struct
    {
        if (!typeof(TEnum).IsEnum)
            throw new InvalidOperationException("Type parameter TEnum must be an enum");

        if (projection == null)
            return Enum.GetValues(typeof (TEnum)).OfType<TEnum>();

        return Enum.GetValues(typeof (TEnum)).OfType<TEnum>().Select(projection);
    }

我在第一次返回时遇到编译时错误。 返回IEnumerable<TEnum>

错误46无法将System.Collections.Generic.IEnumerable<TEnum>类型隐式转换为System.Collections.Generic.IEnumerable<T>

我对T没有任何限制,所以TTEnum更通用。 IEnumerable<out T> T是可变的,为什么我仍然得到错误?

协方差仅适用于两种类型之间存在多态关系的情况。 在您的情况下, TEnumT TEnum于相关,因此协方差不适用。

您可以通过将枚举成员直接转换为目标类型来轻松解决此问题:

if (projection == null)
    return Enum.GetValues(typeof(TEnum)).OfType<T>();

编辑 :我建议删除projection参数,并更简单地定义您的方法:

public static IEnumerable<TEnum> AsEnumerable<TEnum>() where TEnum : struct
{
    if (!typeof(TEnum).IsEnum)
        throw new InvalidOperationException("Type parameter TEnum must be an enum");

    return Enum.GetValues(typeof(TEnum)).OfType<TEnum>();
}

如果确实需要执行投影,可以对返回的序列使用标准的LINQ Select操作:

var optionsA = AsEnumerable<RegexOptions>();
var optionsB = AsEnumerable<RegexOptions>().Select(o => o.ToString());

这将为您提供与代码几乎相同的简洁性,但省去了维护可选参数的麻烦。

编辑2 :如果你真的想为投影定义一个重载,我建议实现其中的所有逻辑,然后使用无参数版本中的标识函数调用它:

public static IEnumerable<TEnum> AsEnumerable<TEnum>() where TEnum : struct
{
    return AsEnumerable<TEnum, TEnum>(e => e);
}

public static IEnumerable<TResult> AsEnumerable<TEnum, TResult>(
    Func<TEnum, TResult> projection) where TEnum : struct
{
    if (!typeof(TEnum).IsEnum)
        throw new InvalidOperationException("Type parameter TEnum must be an enum");

    return Enum.GetValues(typeof(TEnum)).OfType<TEnum>().Select(projection);
}

示例电话:

var optionsA = AsEnumerable<RegexOptions>();
var optionsB = AsEnumerable<RegexOptions, string>(o => o.ToString());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM