首先,我无法理解.NET 3.5的功能/ Lambda方面。我每天都在LINQ中使用这些功能,但我的问题是了解实现,以及它们的真正含义(Lambda?System.Func?等等)
考虑到这一点,将如何实现以下目标:
作为一个例子,我想要一个List(Of T)的Extension方法,它将List中所有对象的属性设置为某个值,并返回更新的List(Of T)。会像这样调用:
VB:
Dim someList As List(Of TextBox) = (New List(Of TextBox)).UpdateExtension(Function(txtb) txtb.Text = "something")
C#:
List<TextBox> someList = (new List<TextBox>()).UpdateExtension(txtb => txtb.Text = "something");
在VB和C#中,Extension方法会是什么样子?
即:
<Extension()> _
Public Function UpdateExtension(Of T)(ByVal source As List(Of T), ByVal predicate As ??) As List(Of T)
'??
End Function
喝彩!
修改
正如许多人所指出的,使用.ForEach()或多或少可以实现上述目标。但我的兴趣在于如何实现类似.ForEach()的实现,即我对上述问题的解决方案的实现感兴趣。
答案 0 :(得分:2)
除了您要修改列表而不是返回新列表之外,这只是.ForEach()
调用。
要真正理解这是如何运作的,请考虑IEnumerable
而不是列表。想想为什么下面的两个表达式具有相同的结果和为什么后者通常更可取:
MyEnumerable.Count() > 2
MyEnumerable.Skip(2).Any()
为了帮助实现这一目标,请使用C#的yield
关键字重新实现一些标准的IEnumerable扩展。一旦你真正理解为什么第二个表现更好,你应该保持良好状态。
对于不同的基本委托类型,您只需要学习它们。将Func
视为基本的公共委托,您可以在其中指定泛型类型参数的参数类型和返回类型。然后将Action
视为Func
的特殊情况,其中返回类型为void,Predicate
作为返回类型为bool的特殊情况。
答案 1 :(得分:2)
你真的是在这里嘲笑和匹配扩展方法。它几乎是Select和ForEach的组合。您似乎需要一种方法,允许您修改列表的元素并返回原始枚举。以下应该为你做的伎俩。
VB.Net
<Extension()> _
Public Function UpdateExtension(Of T)(ByVal source As IEnumerable(Of T), ByVal del As Action(Of T)) As IEnumerable(Of T)
For Each cur in source
del(cur)
Next
Return source
End Function
C#
public static IEnumerable<T> UpdateExtension<T>(this IEnumerable<T> source, Action<T> del) {
foreach ( var cur in source ) {
del(cur);
}
return source;
}
答案 2 :(得分:1)
扩展是通过静态方法在静态类中实现的,这些方法将扩展的目标作为此关键字前面的第一个参数。为了实现你的例子,我会这样做:
public static class ListBoxExtensions
{
public static List<TextBox> SetToValue(this List<TextBox> txtBoxes, string sValue)
{
txtBoxes.ForEach(txtBox => txtBox.Text = sValue);
return txtBoxes;
}
}
并在具有3个文本框的Windows窗体上使用它:
private void Form1_Load(object sender, EventArgs e)
{
List<TextBox> boxes = new List<TextBox>
{
textBox1,
textBox2,
textBox3
}.SetToValue("Hello");
}
抱歉 - 不要说VB。
希望这有帮助。