2009-05-29 71 views
0

所以我有一个由Bloops集合创建的Razzies集合。我使用Linq查询来检索这个集合。查询请参考:Linq Select Certain Properties Into Another Object?在集合中的所有对象上运行一个方法

我想知道是否有可能在返回集合之前,甚至在刚刚使用for循环之前,在所有新创建的Razzies上运行一个方法。

我尝试这样做:

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

但它没有返回。

回答

2

拉斯,这可能会做你想做的。这是一个非常简单的方法。如果这不是你想要的,请扩展你的问题。

这会在您列举的每个元素上运行该方法。它会而不是运行该方法,直到您枚举,但您可以安全地知道在您使用数据之前运行方法运行。

编辑由于您使用的是密封的第三方类,请使用扩展方法。这就是他们的目的。 ;)使用扩展方法的修改代码。

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(); 
    } 
} 
+0

这个“会”起作用,但在我的真实代码中,Razzie类是我没有源代码的库的一部分,因此“MyMethod”是一个空格,不会返回任何内容。 – 2009-05-29 21:55:33

0

我不确定RunVoid是什么意思。虚拟表示没有回报,但您将结果分配给一个值。

你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 
+0

是的,我想上运行前夕方法ry项目然后返回原始集合。原因是该方法设置了一些我无法直接访问的“只读”属性。 所以你说我坚持循环? – 2009-05-29 21:30:24

+0

@Russ,你一直在定义循环。现在你已经定义了RunVoid,你可以为任何实现IEnumerable(Of T)的集合调用它。如果将它粘贴到应用程序中的模块中,您的示例应该编译并运行 – JaredPar 2009-05-29 21:35:15

1

在初始处理后使用foreach循环是执行此操作的正常方法。如果你不想使用foreach循环,你需要定义你自己的扩展方法来处理这种情况。

+0

我唯一遇到的问题是我需要访问原始Bloop类的属性(我更新了我的代码以反映),所以我会限于嵌套循环?在那种情况下,为了表现,我需要一起摆脱linq呼叫? – 2009-05-29 21:40:20

0

为什么不这样做是正常的,未经评估的方式?你可以使用扩展方法做一堆花哨的东西......但是你可能通过使用扩展方法执行更新来破坏纯度规则......并且这也使得难以理解。试试这个:

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

foreach (var result in results) 
{ 
    result.Razzie.UpdateAddress(result.Address); 
} 
0

如果你正在寻找抽象掉foreach循环,我只是写了IEnumerable <牛逼>的扩展方法是复制列表<牛逼>的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()); 
相关问题