2009-05-29 75 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()); 
相關問題