Я хочу быть в состоянии записать дополнительные методы так, чтобы я мог сказать:
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;
}
}
}
Вы должны изменить содержимое List
, переданного методу расширения, а не переменную, которая содержит ссылку на список:
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");
}
}
Вам придется изменить содержимое исходного списка - простое переназначение параметра на другое значение не поможет. Примерно так:
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, хотя мы прибыли туда независимо. Я все равно сохраняю этот ответ, так как он содержит больше, чем код.)
Если это ссылочный тип, вам придется изменить его содержимое. Если вы передаете тип значения, вам не повезло. Само существование методов расширения используется для поддержки функциональных парадигм в C #, и эти функциональные парадигмы, по самой своей сути, имеют тенденцию к неизменности типов, отсюда и невозможность изменить значение, от которого вызывается метод расширения.
Другими словами, хотя вы могли это сделать, это может не соответствовать «духу» функционального программирования.