2010-09-17 43 views
4

((IEnumerable)source).OfType<T>()source as IEnumerable<T>之间有什么区别((IEnumerable)source).OfType <T>()和source为IEnumerable <T>之间的区别是什么?

对我来说它们看起来很相似,但它们不是!

source的类型为IEnumerable<T>,但它被装箱为object

编辑

这里是一些代码:

public class PagedList<T> : List<T>, IPagedList 
{ 
    public PagedList(object source, int index, int pageSize, int totalCount) 
    { 
     if (source == null) 
      throw new ArgumentNullException("The source is null!"); 


     // as IEnumerable<T> gives me only null 

     IEnumerable<T> list = ((IEnumerable)source).OfType<T>(); 

     if (list == null) 
      throw new ArgumentException(String.Format("The source is not of type {0}, the type is {1}", typeof(T).Name, source.GetType().Name)); 

     PagerInfo = new PagerInfo 
         { 
          TotalCount = totalCount, 
          PageSize = pageSize, 
          PageIndex = index, 
          TotalPages = totalCount/pageSize 
         }; 

     if (PagerInfo.TotalCount % pageSize > 0) 
      PagerInfo.TotalPages++; 

     AddRange(list); 
    } 

    public PagerInfo PagerInfo { get; set; } 
} 

在另一个地方我创建了一个PagedList的实例

public static object MapToPagedList<TSource, TDestination>(TSource model, int page, int pageSize, int totalCount) where TSource : IEnumerable 
{ 
    var viewModelDestinationType = typeof(TDestination); 
    var viewModelDestinationGenericType = viewModelDestinationType.GetGenericArguments().FirstOrDefault(); 

    var mappedList = MapAndCreateSubList(model, viewModelDestinationGenericType); 

    Type listT = typeof(PagedList<>).MakeGenericType(new[] { viewModelDestinationGenericType }); 
    object list = Activator.CreateInstance(listT, new[] { (object) mappedList, page, pageSize, totalCount }); 

    return list; 
} 

如果有人能告诉我为什么我必须施放mappedList到object,我真的很感激:)

这里的MapAndCreateSubList方法和Map委托:

private static List<object> MapAndCreateSubList(IEnumerable model, Type destinationType) 
{ 
    return (from object obj in model select Map(obj, obj.GetType(), destinationType)).ToList(); 
} 

public static Func<object, Type, Type, object> Map = (a, b, c) => 
{ 
    throw new InvalidOperationException(
     "The Mapping function must be set on the AutoMapperResult class"); 
}; 
+1

这是一个测验问题?你好像忽略了一些信息。无论如何,OfType 将enumerable过滤为只有这种类型的元素,所以这是最大的区别。 – 2010-09-17 21:53:36

+0

我在我的代码源中使用IEnumerable ,并证明它不是null,但它是空的。我看着调试器,我看到T是正确的。然后我使用((IEnumerable)源).OfType ()和铸造是正确的,没有空结果。如果你想我可以发布更多的代码。 – Rookian 2010-09-17 21:56:21

回答

12

((IEnumerable)source).OfType<T>()source as IEnumerable<T>有什么区别对我来说他们看起来很相似,但他们不是!

你说得对。他们是非常不同的。

前者意味着“采取源序列并产生一个全新的,不同的序列,该序列由先前序列中给定类型的所有元素组成”。

后者的意思是“如果源序列的运行时类型是给定类型,那么给我一个该序列的引用,否则给我null”。

让我用一个例子来说明。假设你有:

IEnumerable<Animal> animals = new Animal[] { giraffe, tiger }; 
IEnumerable<Tiger> tigers = animals.OfType<Tiger>(); 

这会给你一个新的,不同的序列,其中包含一个单一的老虎。

IEnumerable<Mammal> mammals = animals as IEnumerable<Mammal>; 

这会给你null。动物不是一系列哺乳动物,尽管它是一系列只发生在哺乳动物身上的动物。动物的实际运行时间类型是“动物阵列”,并且一系列动物与哺乳动物序列不具有类型兼容性。为什么不?那么,假设转换工作,然后你说:

animals[0] = snake; 
Mammal mammal = mammals.First(); 

哎,你只要把蛇成只能包含哺乳动物的变量!我们不能允许,所以转换不起作用。

在C#4中你可以走另一条路。你可以这样做:

IEnumerable<Object> objects = animals as IEnumerable<Object>; 

因为动物的阵列可以被为对象的序列治疗。你在那里放一条蛇,一条蛇仍然是一个物体。这只适用于C#4。 (而且只工作,如果这两种类型都参考的类型。你不能把一个int数组对象的序列。)

但要明白事情的关键是,OfType<T>方法返回一个崭新序列,“as”运算符执行运行时类型测试。这些是完全不同的东西。

这是另一种看待它的方法。

tigers = animals.OfType<Tiger>()是基本相同

tigers = animals.Where(x=>x is Tiger).Select(x=>(Tiger)x); 

即,通过做动物的每个成员的一个测试,看它是否是一个老虎产生一个新的序列。如果是这样,就投它。如果不是,则丢弃它。

mammals = animals as IEnumerable<Mammal>,另一方面,是基本相同

if (animals is IEnumerable<Mammal>) 
    mammals = (IEnumerable<Mammal>) animals; 
else 
    mammals = null; 

有意义吗?

3

OfType<T>()将只返回的类型T的内部枚举类型所以,如果你有这样的

object[] myObjects = new object[] { 1, 2, "hi", "there" }; 

然后调用

var myStrings = myObjects.OfType<string>(); 

然后,myStrings将是一个可跳过1和2并只返回“hi”和“there”的枚举类型。您无法将我的对象投射到IEnumerable<string>,因为这不是它的原因。

其他运营商类似这里是Cast<T>(),这将尝试施放的所有项目键入T.

var myStrings = myObjects.Cast<string>(); 

一旦你开始在这种情况下迭代myStrings,你会得到一个InvalidCastException,因为它会尝试将1投射到一个字符串并失败。

+0

是的,但我的类型都是一样的。是Cast 类似于IEnumerable ? – Rookian 2010-09-17 22:07:32

相关问题