Я не утверждаю, что код в этом ответе полезен, но (он работает и), я думаю, он иллюстрирует то, что вам нужно для того, чтобы ваш подход работал. Аргумент должен быть помечен ref
. BCL не имеет тип делегата с ref
, поэтому просто напишите свой собственный (не внутри какого-либо класса):
public delegate void MyActionRef<T>(ref T arg);
С этим ваш метод становится:
public static void ForEach2<T>(this T[] list, MyActionRef<T> actionRef)
{
if (actionRef == null)
throw new ArgumentNullException("actionRef");
for (int idx = 0; idx < list.Length; idx++)
{
actionRef(ref list[idx]);
}
}
Теперь не забудьте использовать ключевое слово ref
в своем методе тестирования:
numbers.ForEach2((ref int num) =>
{
num = 0;
});
Это работает, потому что можно передать запись массива ByRef (ref
).
Если вы хотите расширить IList<>
вместо этого, вы должны сделать:
public static void ForEach3<T>(this IList<T> list, MyActionRef<T> actionRef)
{
if (actionRef == null)
throw new ArgumentNullException("actionRef");
for (int idx = 0; idx < list.Count; idx++)
{
var temp = list[idx];
actionRef(ref temp);
list[idx] = temp;
}
}
Надеюсь, это поможет вам понять.
Примечание: мне пришлось использовать петли for
. В C # в foreach (var x in Yyyy) { /* ... */ }
запрещено присваивать значение x
(что включает в себя передачу x
ByRef (с ref
или out
)) внутри тела цикла.