【问题标题】:Convert generic parameter of type T to List<TP> when T is IEnumerable<TP>当 T 为 IEnumerable<TP> 时,将 T 类型的泛型参数转换为 List<TP>
【发布时间】:2014-03-19 08:29:55
【问题描述】:

我的应用程序有一个缓存值的方法。我需要第二种方法来检查 T 类型的泛型参数是否实现了 IEnumerable 而不是实现了 IList。如果答案是肯定的,该方法应该执行一个 .ToList 并将其转换回 T(参见代码示例中的注释)。

你能告诉我如何使用 .ToList() 将一个转换为 T 的 List 返回吗?(真的有可能吗?)

类似这样的:

public T ToListIfIEnumerable<T>(T value)
{
    var needToCovert = TypeImplementsGenericIEnumerableButNotGenericIList(value);

    if (!needToCovert)
    {
        return value;
    }

    // return value.ToList() <-- How to do that???
}

private bool TypeImplementsGenericIEnumerableButNotGenericIList<T>(T value)
{
    var type = value.GetType();

    var interfaces = type.GetInterfaces();
    var gi = typeof(IEnumerable<>);
    var gl = typeof(IList<>);

    // It would be better if the next lines did't compare strings!
    // Suggestions welcome...
    var implementsIEnumerable = interfaces.Any(
        i => i.IsGenericType && i.Name == gi.Name && i.Namespace == gi.Namespace);
    var implementsIList = interfaces.Any(
        i => i.IsGenericType && i.Name == gl.Name && i.Namespace == gl.Namespace);

    return implementsIEnumerable && !implementsIList;
}

背景信息: 使用该方法的对象执行类似 Lazy 的操作。缓存 IEnumerable 在以下示例中没有多大意义:Enumerable.Range(1, 3).Select(i =&gt; Guid.NewGuid()) 每次调用它时都会提供新的 Guid。这就是为什么我想做一个 ToList()。

【问题讨论】:

    标签: c# linq generics reflection linq-to-objects


    【解决方案1】:

    如果您不介意使用dynamic,动态输入和重载可能会有所帮助:

    object ConvertToListIfNecessary(dynamic input)
    {
        return MaybeToList(input);
    }
    
    private IList<T> MaybeToList<T>(IEnumerable<T> input)
    {
        return input.ToList();
    }
    
    private IList<T> MaybeToList<T>(IList<T> input)
    {
        return input;
    }
    
    private object MaybeToList(object input)
    {
        // Take whatever action you want if the input *doesn't* implement
        // IEnumerable<T>
    }
    

    基本上,这让dynamic 背后的聪明才智为你做蹩脚的反射工作。它可能不如手卷的东西那么快,但它可能更容易做对。

    【讨论】:

    • 谢谢,这就是我想要的!我不太喜欢 Dynmic 的东西,但我在私有方法中这样做,它在其他类中不可见,然后我就不在乎了。它为我节省了很多反思。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多