我希望能够编写扩展方法,这样我就可以说:
lines.ForceSpaceGroupsToBeTabs();而不是:
lines = lines.ForceSpaceGroupsToBeTabs();然而,以下代码目前输出:
....one
........two而不是:
Tone
TTtwo,我需要修改以下代码才能使其输出:
Tone
TTtwo(请注意,对于可见性,. = space, T = \t):
using System;
using System.Collections.Generic;
namespace TestExtended82343
{
class Program
{
static void Main(string[] args)
{
List<string> lines = new List<string>();
lines.Add("....one");
lines.Add("........two");
lines.ForceSpaceGroupsToBeTabs();
lines.ForEach(l => Console.WriteLine(l));
Console.ReadLine();
}
}
public static class Helpers
{
public static void ForceSpaceGroupsToBeTabs(this List<string> originalLines)
{
string spaceGroup = new String('.', 4);
List<string> lines = new List<string>();
foreach (var originalLine in originalLines)
{
lines.Add(originalLine.Replace(spaceGroup, "T"));
}
originalLines = lines;
}
}
}发布于 2010-02-24 14:40:55
您必须修改传递给扩展方法的List<string>的内容,而不是保存对列表的引用的变量:
public static void ForceSpaceGroupsToBeTabs(this List<string> lines)
{
string spaceGroup = new String('.', 4);
for (int i = 0; i < lines.Count; i++)
{
lines[i] = lines[i].Replace(spaceGroup, "T");
}
}发布于 2010-02-24 14:41:13
您必须更改原始列表的内容--只是重新分配参数以获得不同的值并不能做到这一点。就像这样:
public static void ForceSpaceGroupsToBeTabs(this List<string> lines)
{
string spaceGroup = new String('.', 4);
for (int i = 0; i < lines.Count; i++)
{
lines[i] = lines[i].Replace(spaceGroup, "T");
}
}值得注意的是,这与扩展方法无关。想象一下你刚刚打电话来:
Helpers.ForceSpaceGroupsToBeTabs(lines);..。因为这就是代码被有效转换成的内容。它是一个扩展方法,这一点没有什么特别之处;如果您更改了代码,使“普通”静态方法能够工作,那么它也将作为扩展方法工作。正如注释中所指出的,扩展方法不能做的一件事是将第一个参数设置为ref参数。
(编辑:我知道这是dtb发布的完全相同的代码,尽管我们是独立到达那里的。我仍然保留这个答案,因为它不仅仅是代码。)
发布于 2010-02-24 14:42:04
如果它是引用类型,则必须更改它的内容。如果它是你传递的值类型,那么你就不走运了。扩展方法的存在正是为了支持C#中的功能范式,而这些功能范式本质上倾向于类型的不变性,从而无法改变被称为扩展方法的价值。
换句话说,虽然您可以这样做,但它可能不符合函数式编程的“精神”。
https://stackoverflow.com/questions/2326734
复制相似问题