簡體   English   中英

((IEnumerable)source).OfType有什么區別 <T> ()和源為IEnumerable <T>

[英]What is the difference between ((IEnumerable)source).OfType<T>() and source as IEnumerable<T>

((IEnumerable)source).OfType<T>()source as 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轉換為對象,我會非常感激:)

這里是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");
};

有什么區別((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;

說得通?

OfType<T>()只返回枚舉中類型為T的類型。所以如果你有這個

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

然后打電話

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

然后myStrings將是一個可以跳過1和2的枚舉,只返回“hi”和“there”。 你不能將myObjects強制轉換為IEnumerable<string> ,因為那不是它的本質。

這里類似的另一個運算符是Cast<T>() ,它將嘗試將所有項目Cast<T>()為類型T.

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

在這種情況下,一旦開始迭代myStrings,您將獲得InvalidCastException ,因為它將嘗試將1 InvalidCastException為字符串並失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM