Невозможно преобразовать из «группы методов» в «System.Action<byte, byte, bool[*,*]>»

Я получаю сообщение об ошибке: 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);
      }
    }
  }
}

В коде используются делегаты и ссылки, что усложняет ситуацию. Где я неправ.

удалить ref из последнего параметра eraser

Selvin 24.06.2024 12:21

@Selvin массивы не передаются по ссылке, если вы не используете ref/out, как и буквально любой другой параметр. То, что они являются ссылкой, — это не одно и то же.

Servy 24.06.2024 16:31

Они передаются как ссылка... но это копия. Я не использовал слово "по"

Selvin 25.06.2024 09:15

Также код имеет запах C.... В C массив передается как копия, поэтому вы не можете изменять его элементы. Вот почему я написал это. Пока OP просто хочет изменить элементы ref, нет необходимости (также из контекста кода это кажется ненужным, поскольку оно вызывается в цикле)

Selvin 25.06.2024 10:02

@selvin Это код Pascal, который был перенесен на C, а затем на C#. У него много запахов, ни один из них не приятный.

Gerhard 26.06.2024 09:15
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
78
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Сообщение не очень понятное, но проблема в том, что вы проходите 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);

Другие вопросы по теме