Передача структуры через действие в C # не компилируется - PullRequest
1 голос
/ 03 августа 2011

У меня есть код, который отлично работает и компилируется, где у меня есть Action, определенное как:

Action<double, double, double ....> OnBlah;

Теперь у меня более 16 параметров, поэтому я хочу вместо этого передать структуру, поэтому я определилдействие как:

Action<structName> OnBlah;

Но я получаю ошибку в компиляторе C #, которая говорит, что structName не инициализировано.Это странно, поскольку:

A.Ранее в коде я непосредственно передавал двойные параметры OnBlah из структуры.

B.Структуры инициализируются по определению.

Я использую VS 2010, полагаю, это ошибка компилятора?

Добавлен код воспроизведения для ошибки компилятора:

namespace CompilerBug
{
    struct Test
    {
        public double a;
    }

    class Program
    {
        static Action<Test> OnBlah;

        static void DoesCompileOk()
        {
            Test test;
            test.a = 5;
            OnBlah(test);
        }

        static void DoesNotCompileOk()
        {
            Test test;
            int b = 0;
            if (b == 4)
            {
                test.a = 5;
            }
            OnBlah(test);
        }

        static void Main(string[] args)
        {
            OnBlah = (t) => { };
        }
    }
}

Ответы [ 2 ]

1 голос
/ 03 августа 2011

Это не ошибка компилятора. Сначала нужно инициализировать структуру, как говорит компилятор. Предположительно ваша ошибка на самом деле в коде, который вызывает делегат, поскольку больше ничего не имеет смысла.

Когда вы вызывали делегата с вашей двойной версией из 16 параметров, двойные параметры были инициализированы. Если бы вы не инициализировали их, компилятор выдал бы ту же ошибку. Например:

private static void actDouble(double d)
{
}

static void Main(string[] args)
{
    double d;
    Action<double> act = actDouble;
    act(d);//error on this line
}

Это не компилируется со следующей ошибкой:

error CS0165: Use of unassigned local variable 'd'

Нет ничего особенного в структурах в этом отношении.

Как правило, ваша первая догадка, когда вы сталкиваетесь с синтаксической ошибкой, никогда не должна заключаться в том, что это ошибка компилятора. Ошибки компилятора чрезвычайно редки, особенно в столь широко используемом компиляторе, как этот.


Обновление после редактирования вопроса, в котором добавлен реальный код

Test test;
int b = 0;
if (b == 4)
{
    test.a = 5;
}
OnBlah(test);

Компилятор не уверен, что test полностью инициализирован. Это не делает анализ потока программы. Вы можете решить проблему, убедившись, что компилятор знает, что структура полностью инициализирована.

0 голосов
/ 03 августа 2011
Action<structName> OnBlah;

никогда не может вызвать ошибку, которую вы цитируете; если ни один из двух типов Action или structName не может быть разрешен, он будет жаловаться - и если аргумент универсального типа не подходит, он будет жаловаться, но это ожидается.

Если OnBlah - это поле , оно автоматически инициализируется нулем; если это переменная , ее необходимо будет присвоить перед использованием. Он может быть назначен на null, но если это так, он потерпит неудачу во время выполнения, когда вы попытаетесь вызвать его (если только вы не выполните нулевую проверку). Итак, мы приходим, чтобы призвать; если мы предполагаем ненулевое значение, вам нужно указать аргумент, т.е.

OnBlah(someValue); // or OnBlah.Invoke(someValue);

здесь, если someValue не был определен , произойдет ошибка; если он не определенно назначен , это приведет к ошибке. Для определенного присвоения присваиваются поля ; переменные не инициализируются.

В случае структур значение инициализируется либо с помощью конструктора (или другого метода, который возвращает значение), или путем ручной установки каждое поле (что не должно быть возможным, поскольку структуры a: structs должны быть неизменными, а поля b: должны быть закрытыми).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...