2013-11-14 2 views
4

Я работаю в базе кода, в которой много коллекций первого класса.Универсальный метод расширения для преобразования из одной коллекции в другую

Для того, чтобы облегчить использование этих коллекций с помощью LINQ, есть метод расширения в коллекции, которая выглядит следующим образом:

public static class CustomCollectionExtensions 
{ 
    public static CustomCollection ToCustomCollection(this IEnumerable<CustomItem> enumerable) 
    { 
     return new CustomCollection(enumerable); 
    } 
} 

С сопроводительные конструкторами:

public class CustomCollection : List<CustomItem> 
{ 
    public CustomCollection(IEnumerable<CustomItem> enumerable) : base(enumerable) { } 
} 

Это ветры будучи гроздь шаблона, поэтому я попытался написать общий код IEnumerable<U>.To<T>(), так что нам не пришлось бы генерировать эти конкретные методы ToXCollection().

я добрался до:

public static class GenericCollectionExtensions 
{ 
    public static T To<T, U>(this IEnumerable<U> enumerable) where T : ICollection<U>, new() 
    { 
     T collection = new T(); 
     foreach (U u in enumerable) 
     { 
      collection.Add(u); 
     } 
     return collection; 
    } 
} 

Который должен быть назван как customCollectionInstance.OrderBy(i => i.Property).To<CustomCollection, CustomItem>()

Есть ли способ, чтобы избежать необходимости указывать CustomItem тип, поэтому мы можем использовать вместо customCollectionInstance.OrderBy(i => i.Property).To<CustomCollection>() или это не что можно сделать в целом?

+2

Боюсь, что нет. – MarcinJuraszek

+0

Почему именно у вас так много разных коллекций? Это похоже на запах кода для меня. – svick

+0

@svick - существует множество коллекций, потому что это большая база кода, а коллекции первого класса были/предпочитаются коллекциями общих коллекций, чтобы где-то инкапсулировать правила на основе набора, а не определять их относительно общего IWhatever . Я не уверен, было ли это хорошим или плохим решением, но я знаю, что 'var a = Member.Offers.ActiveOffers()' выглядит немного чище, чем использовать .Where() каждый раз. –

ответ

5

Что-то близко к тому, что вы хотите:

public static class GenericCollectionExtensions 
{ 
    public sealed class CollectionConverter<TItem> 
    { 
     private readonly IEnumerable<TItem> _source; 

     public CollectionConverter(IEnumerable<TItem> source) 
     { 
      _source = source; 
     } 

     public TCollection To<TCollection>() 
      where TCollection : ICollection<TItem>, new() 
     { 
      var collection = new TCollection(); 
      foreach(var item in _source) 
      { 
       collection.Add(item); 
      } 
      return collection; 
     } 
    } 

    public static CollectionConverter<T> Convert<T>(this IEnumerable<T> sequence) 
    { 
     return new CollectionConverter<T>(sequence); 
    } 
} 

Использование:

customCollectionInstance.OrderBy(i => i.Property).Convert().To<CustomCollection>(); 
Смежные вопросы