|
2018/05/18(Fri) 09:44:41 編集(投稿者)
■No87402 (いずみ さん) に返信 > Visual Basicにおいて、これと同様の処理を行いたく、以下のように記述すればよいのかと考えたのですが、うまくいきません。
VB では、代入操作が『式』ではなく、『文(ステートメント)』だからですね。
C# にとっての .Select(r => r["col2"] = "changed") というコードは、Visual Basic においては .Select(Function(r) r("col2") = "changed" Return "changed" End Function) に相当するというわけで。
> 列の値を一括更新するためには 無理せず、For Each ループで書いた方が良い気もしますが、 どうしてもワンライナーにしたいのであれば、代入操作のために
・ステートメント実行のため、Func を受け取るメソッドではなく、Action を受け取るメソッドを使う → 例:ForEach メソッド
・代入処理と同時に、何かしらの値を返すメソッドを併用する → 例:CallByName、Interlocked.Exchange メソッドなど
といった手法をとることができます。
【案1】 // C# Array.ForEach(dt.Select("col1='A02'"), r => r["col2"] = "changed"); ' Visual Basic Array.ForEach(dt.Select("col1='A02'"), Sub(r) r!col2 = "changed")
【案2】 // C# dt.AsEnumerable().Where(r => r.Field<string>("col1") == "A02").Select(r => r["col2"] = "changed").ToArray(); ' Visual Basic dt.AsEnumerable().Where(Function(r) r.Field(Of String)("col1") = "A02").Select(Function(r) CallByName(r, Nothing, CallType.Let, "col2", "changed")).ToArray() ' Visual Basic dt.AsEnumerable().Where(Function(r) "A02".Equals(r!col1)).Select(Function(r) Interlocked.Exchange(r!col2, "changed")).ToArray()
【案3】 // C# (from r in dt.AsEnumerable() where r.Field<string>("col1") == "A02" select r).ToList().ForEach(r => r["col2"] = "changed"); // C# dt.AsEnumerable().Where(r => r.Field<string>("col1") == "A02").ToList().ForEach(r => r["col2"] = "changed"); ' Visual Basic Call (From r In dt Where r.Field(Of String)("col1") = "A02").ToList().ForEach(Sub(r) r!col2 = "changed") ' Visual Basic dt.AsEnumerable().Where(Function(r) r.Field(Of String)("col1") = "A02").ToList().ForEach(Sub(r) r!col2 = "changed")
|