C# как я могу передать доступ к переменным в виде выражения или текста

#c# #expression #ref

Вопрос:

Я пишу специальный компилятор для управления машинами. С одной стороны, это должно генерировать машинный код из кода C#, с другой стороны, тот же код должен использоваться для моделирования.

Определение памяти получит адрес через менеджер (для машинного кода), но в моделировании это должно содержать значение.

В коде иногда вместо значения необходимо передавать адрес. Если у меня есть вызов (имя переменной и т.д.) Я могу сам решить этот адрес в симуляции.

Граничные условия:

  • для передачи я открыт для всех идей!!!
  • из-за смещений массива в старой системе мне приходится обращаться к массивам с помощью методов, поэтому метод обращается
  • чтобы передать их методам по ссылке как прямое значение, метод должен быть запрограммирован как метод ‘ref’
  • код должен автоматически корректироваться при изменении переменных (например, переименовании в Visual Studio).

Я отверг следующие подходы:

передача в виде строки

-> не обновляется при переименовании, не компилируется

 double addr = getAddress3("Mem.PROBE_SET[1]");
 

передача в виде строки с именем

-> возможно, но не легко использовать

 double addr = getAddress3($"{nameof(Mem)}.{nameof(Mem.PROBE_SET)}[1]");

private double getAddress3(string expression)
{
  // Resolve text Expression
  //double addr = MemoryResolver.resolveExpression(expression); 
  return 0.0;
}
 

Мое реальное решение, в качестве примера кода:

GetAddress2 был бы моим предпочтительным решением, потому что вызов такой же, как и тогда, когда я хочу обратиться к sepicher как к значению, и также очень короткий. К сожалению, у меня здесь проблема с «ссылкой»! У кого-нибудь есть идеи, как я мог бы сделать это лучше?

     public class Test
    {
      private ExampleMemory Mem = new ExampleMemory();

      public Test()
      {
        // booth calls could compile, but no info about anonymus method content in GetAddress
        double addr1 = GetAddress(() => Mem.getProbePos(1));
        double addr2 = GetAddress(() => Mem.PROBE_SET[1]);

        // only addr4 could compile, error CS8153 because ref is used
        //double addr3 = GetAddress2(() => Mem.getProbePos(1)); // Error CS8153
        double addr4 = GetAddress2(() => Mem.PROBE_SET[1]); // Works fine
      }

      private double GetAddress(Func<double> func)
      {
        // no access to source call.... :-( cannot resolve memory
        return 0.0;
      }

      private double GetAddress2(Expression<Func<double>> expr)
      {
        string info = expr.Body.ToString();
        // Infos from Call available => Here i can work with Men.PROBE_SET[1] info and can resolve the memory internally....

        return 0.0;
      }
    }

    public class ExampleMemory
    {
      private int[] PROBE_POS = new int[4];  // with array offset
      public int[] PROBE_SET = new int[4];   // without offset => direct access

      [ArrayOffsetAttribute(Offset = 1)]
      public ref int getProbePos(int index)
      {
        return ref PROBE_POS[index - 1];
      }
    }
 

To summarize again what I have in mind,
a solution for:

         // Work with the memroy value
        var val = Mem.getProbePos(3); // assign e.g. 23

        // Work with address of memory
        var addr = GetAddress(/* ... of Mem.getProbePos(3) ...*/); // assign e.g. control address 1723
 

В методе getAddress я могу использовать что угодно, чтобы получить адрес. Например, через отражение исходной сборки Mem. и так далее. Но мне нужна информация о том, какая память была вызвана.

Мне любопытны ваши идеи и ответы! Заранее большое спасибо.


Обновите, чтобы загрузить вопрос Pizza

В генераторе каждому полю присваивается адрес из класса памяти Examplemory. Затем класс имеет начальный адрес, например 1300.

Сгенерированный код iso из: double value = Mem.PROBE_SET[1]; может выглядеть следующим образом в ISO, где MemoryManager назначает адрес для адреса локальной памяти. #1 = #1305

Но иногда сам адрес, т. е. 1305, используется для функций управления вместо значения, вот как он может выглядеть в C# CNC.G310(val: value, p: GetAddress(Mem.PROBE_SET[1]), sizeType: "L1"); , и это может быть сгенерированный код ISO: G310 #1 P 1305 L1

Поэтому мне нужен сгенерированный адрес моей переменной, но адрес, который я перенес в свой собственный менеджер памяти. Но мне нужно, по крайней мере, указание, какая память (идентификатор и класс, а также индекс для массивов) использовалась.

Комментарии:

1. Я предполагаю, что вам действительно нужен адрес, а не просто способ редактирования уже определенной переменной (если это так, попробуйте ref ключевое слово). Но кроме этого не совсем понятно, о чем вы просите (для меня). Вы пытаетесь получить адрес какой-то переменной C#? Если это так, вам, вероятно, понадобится unsafe блок и указатели

2. Спасибо за ваш вклад, см. выше мое обновление.