Запустить метод для всех объектов в коллекции - PullRequest
0 голосов
/ 30 мая 2009

Итак, у меня есть коллекция Razzies, созданная из коллекции Bloops. Я получаю эту коллекцию, используя запрос Linq. Ссылка: Linq Выбрать некоторые свойства в другом объекте? для запроса.

Я хотел бы знать, возможно ли запустить метод на всех вновь созданных Razzies перед возвратом коллекции или даже сразу после, без использования цикла for.

Я пробовал это:

Dim results = From item In bloops _
              Select New Razzie() With _
              { _
                  .FirstName = item.FirstName, _
                  .LastName = item.LastName _
              }.UpdateAddress(item.Address)

Но это ничего не возвращает.

Ответы [ 5 ]

2 голосов
/ 30 мая 2009

Расс, это может сделать то, что вы хотите. Это довольно простой подход. Если это не то, что вы хотите, пожалуйста, расширьте свой вопрос.

Это запустит метод для каждого элемента при перечислении. не будет запускать метод до тех пор, пока вы не начнете перечислять, но вы можете смело знать, что метод будет запускаться перед использованием данных.

РЕДАКТИРОВАТЬ Поскольку вы используете запечатанный сторонний класс, используйте методы расширения. Вот для чего они. ;) Изменен код для использования методов расширения.

class MyArgs { }
class Razzie //pretend this is a 3rd party class that we can't edit
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
static class RazzieExtensions
{
    public static Razzie MyMethod(this Razzie razzie, MyArgs args)
    {
        razzie.FirstName = razzie.FirstName.ToUpper();
        return razzie;
    }
}
class Program
{
    static void Main(string[] args)
    {
        var bloops = new List<Razzie>
            {
                new Razzie{FirstName = "name"},
                new Razzie{FirstName = "nAmE"}
            };
        var myArgs = new MyArgs();
        var results = from item in bloops
                      select new Razzie
                      {
                          FirstName = item.FirstName,
                          LastName = item.LastName
                      }.MyMethod(myArgs);

        foreach (var r in results)
            Console.WriteLine(r.FirstName);
        Console.ReadKey();
    }
}
1 голос
/ 30 мая 2009

Использование цикла foreach после начальной обработки - нормальный способ сделать это. Если вы не хотите использовать цикл foreach, вам нужно определить собственный метод расширения для обработки этой ситуации.

0 голосов
/ 30 мая 2009

Если вы хотите абстрагироваться от цикла foreach, я бы просто написал метод расширения для IEnumerable , который дублирует методы List ConvertAll и ForEach, например:

public static IEnumerable<TOutput> ConvertAll<T, TOutput>(this IEnumerable<T> collection, Converter<T, TOutput> converter)
{
    if (converter == null)
        throw new ArgumentNullException("converter");

    List<TOutput> list = new List<TOutput>();

    foreach (T item in collection)
    {
        list.Add(converter(item));
    }

    return list;
}

public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
{
    foreach (T item in collection)
    {
        action(item);
    }
}

Тогда вы можете просто назвать что-то вроде:

bloops
    .ConvertAll(bloop => new Razzie()
                            { 
                                FirstName = bloop.FirstName, 
                                Lastname = bloop.LastName 
                            })
    .ForEach(razzie => razzie.UpdateAddress());
0 голосов
/ 30 мая 2009

Почему бы просто не сделать это обычным, неоцененным способом? Вы можете сделать кучу причудливых вещей с помощью методов расширения ... но вы, вероятно, нарушите правило чистоты, выполнив обновление с помощью метода расширения ... и это также усложнит понимание. Попробуйте это:

var results = from ... select new { Address = item.Address, Razzie = new Razzie { ... }}

foreach (var result in results)
{
    result.Razzie.UpdateAddress(result.Address);
}
0 голосов
/ 30 мая 2009

Я не уверен, что вы подразумеваете под RunVoid. Void не предлагает возврата, но вы присваиваете результаты значению.

Запускаете ли вы RunVoid для выполнения метода для каждого элемента, а затем возвращаете исходную коллекцию? Если это так, встроенного метода не существует, но вы можете добавить его следующим образом.

<Extension>
Public Function RunVoid(Of T)(source As IEnumerable(Of T), del As Action(Of T) As IEnumerable(Of T)
  For Each cur in source
    del(cur)
  Next
  return source
End Function
...