Я получаю сообщение об ошибке:
Error CS1503 Argument 1: cannot convert from 'method group' to 'System.Action<byte, byte, bool[*,*]>'
Это мой минимальный пример кода, который, как мне кажется, должен скомпилироваться, но вызывает вышеупомянутую ошибку:
using System;
public class Program {
void EraseGoodBlocks(bool OverridePreviousTests, ref bool[,] DeviceResults) {
ForAllDevicesResults(eraser, ref DeviceResults);
void eraser(byte BoardNo, byte DeviceNo, ref bool[,] device_results) {}
}
void ForAllDevicesResults(Action<byte, byte, bool[,]> action, ref bool[,] result){
for (byte Board = 0; Board < 4; Board++){
for (byte Device = 0; Device < 16; Device++){
action(Board, Device, result);
}
}
}
}
В коде используются делегаты и ссылки, что усложняет ситуацию. Где я неправ.
@Selvin массивы не передаются по ссылке, если вы не используете ref/out, как и буквально любой другой параметр. То, что они являются ссылкой, — это не одно и то же.
Они передаются как ссылка... но это копия. Я не использовал слово "по"
Также код имеет запах C.... В C массив передается как копия, поэтому вы не можете изменять его элементы. Вот почему я написал это. Пока OP просто хочет изменить элементы ref, нет необходимости (также из контекста кода это кажется ненужным, поскольку оно вызывается в цикле)
@selvin Это код Pascal, который был перенесен на C, а затем на C#. У него много запахов, ни один из них не приятный.





Сообщение не очень понятное, но проблема в том, что вы проходите eraser там, где ожидается Action<byte, byte, bool[,]>. И третий параметр eraser — это ref bool[,], а не bool[,], как ожидалось.
По предложению Селвина вы можете изменить подпись eraser и удалить ref в третьем параметре.
Если вам действительно нужно передать третий параметр делегата как ref bool[,], вы не сможете объявить делегат как действие.
Вместо этого вы должны объявить своего собственного делегата:
delegate void BlockAction(byte BoardNo, byte DeviceNo, ref bool[,] device_results);
И добавьте модификатор ref при его вызове:
delegate void BlockAction(byte BoardNo, byte DeviceNo, ref bool[,] device_results);
void EraseGoodBlocks(bool OverridePreviousTests, ref bool[,] DeviceResults)
{
ForAllDevicesResults(eraser, ref DeviceResults);
void eraser(byte BoardNo, byte DeviceNo, ref bool[,] device_results)
{
}
}
void ForAllDevicesResults(BlockAction action, ref bool[,] result)
{
for (byte Board = 0; Board < 4; Board++)
{
for (byte Device = 0; Device < 16; Device++)
{
action(Board, Device, ref result); // add ref here
}
}
}
Нельзя пройти по ссылке, используя Action. поэтому Action<byte, byte, bool[,]> не совпадает с void eraser(byte BoardNo, byte DeviceNo, ref bool[,] device_results)device_results ожидается, что он будет передан по ссылке. и «Действие<byte, byte, ref bool[,]>» является незаконным. Если вам абсолютно необходимо передать ссылку по ссылке, вы можете создать свой собственный делегат:
delegate void MyDelegate(byte BoardNo, byte DeviceNo, ref bool[,] device_results);
удалить
refиз последнего параметраeraser