如何将非泛型IList转换为IList<T>?

48

我有一个类需要 IList<T>,但我却拥有一个来自NHibernate查询的 Systems.Collection.IList

我想创建一个方法将其转换为 IList<T>。我该怎么做?

7个回答

84
如果您确定所有元素都继承自T(或您使用的其他类型),则...
IList<T> myList = nonGenericList.Cast<T>().ToList();

如果您不确定:

IList<T> myList = nonGenericList.OfType<T>().ToList();

当然,您需要使用 System.Linq 命名空间:
using System.Linq;

6
CastOfType返回的是实现IEnumerable<T>接口的类型,而不是IList<T>类型,因此它们对你没有用处。
调用.Cast<T>().ToList会导致列表的额外复制,可能会对性能产生负面影响。
更好的(我个人认为)方法是创建一个包装类并在运行时进行转换。你需要像这样的东西:
class ListWrapper<T> : IList<T>
{
    private IList m_wrapped;

    //implement all the IList<T> methods ontop of m_wrapped, doing casts
    //or throwing not supported exceptions where appropriate.
    //You can implement 'GetEnumerator()' using iterators. See the docs for 
    //yield return for details
}

那样做的好处是不会创建整个列表的另一个副本。

4
弗雷德里克是正确的。但是Nhibernate也有一个选项可以返回多个结果集。例如:
  IList multiResults = session.CreateMultiCriteria()
                .Add(pageCriteria)
                .Add(countCriteria)
                .List();

在上面的调用中,没有返回一个类型化的列表的选项。因此,必须像上面提到的那样进行强制转换,如下所示:
 IList<T> results = ((IList)multiResults[0]).Cast<T>().ToList();
            IList counts = (IList)multiResults[1];

3
一种方法是使用Linq,例如list.OfType<T>().Cast<T>()

1

Frederik 是正确的,NHibernate 已经实现了这个功能。

var data = query.List<MyType>();

这将导致一个指定类型的IList。在这种情况下,IList<MyType>

1

你不能让NHibernate返回一个IList吗? ICriteria接口定义了一个List<T>方法...


可以的!只需要使用 var result = Session.CreateCriteria(....).List<T>() 替代 .List()。 - stiank81
@stiank81:那是一个修辞问题。;) - Frederik Gheysels
好的 - 我明白了 ;-) 只是在你的详细说明下添加了一条评论,让我更加高兴地学到了这个知识点。 - stiank81
1
我没有看到 CreateMultiCriteria.List() 的 List<T>。 - OutOFTouch

-2

在这种情况下不需要使用Linq(OfType()或.Cast)。 NHibernate实现就足够了。

你只需要使用:

var results= query.List<YourType>();

不是

var results= query.List<>();

IList 没有 List 方法。https://learn.microsoft.com/en-us/dotnet/api/system.collections.ilist?view=net-6.0#methods - EduBic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接