Проблема с преобразованием процедуры delphi в C#

Я был в этом немного без везения.

У меня есть эта процедура Delphi, которую я не писал, и у меня нет исходной программы для тестирования. Пожалуйста, обратите внимание на комментарий, чтобы увидеть, что он должен делать:

// first parameter is an input string, and the others are returned contents
// parsed. Example: "Okay:C15" would be parsed as "Okay", "C", 15, 0
procedure TestingThis(const astring: string; var aname: string;
                     var atype: char; var alength: byte; var adecimals: byte);
var
  ipos,jpos: integer;
  aa: string;
begin
  aname:='';
  atype:='C';
  alength:=1;
  adecimals:=0;
  aa:=astring;
  ipos:=pos(':',aa);
  if ipos > 1 then
  begin
     aname:=copy(aa,1,ipos-1);
     aa:=copy(aa,ipos+1,length(aa)-ipos);
     atype:=aa[1];
     if atype = 'A' then exit;
     if atype = 'B' then
     begin
       alength:=8;
       exit;
     end;
     if atype = 'C' then
     begin
        alength:=strtoint(copy(aa,2,length(aa)-1));
        exit;
     end;
     if atype = 'D' then
     begin
       jpos:=pos('.',aa);  
       if jpos < 1 then  
       begin
         alength:=strtoint(copy(aa,2,length(aa)-1));
         adecimals:=0;
       end
       else
       begin
         alength:=strtoint(copy(aa,2,jpos-2));
         adecimals:=strtoint(copy(aa,jpos+1,length(aa)-jpos));
       end;
       exit;
     end;
  end;
end;

Вот моя версия С#:

public static void TestingThis(string astring)
        {
            int ipos;
            int jpos;
            string aa;
            string aname = "";
            char atype = 'C';
            // def
            byte alength = 1;
            byte adecimals = 0;
            aa = astring;
            ipos = aa.IndexOf(':'); 

            if (ipos > 0)
            {
                aname = aa.Substring(0,ipos); 
                aa = aa.Substring(ipos + 1, aa.Length - ipos - 1); 
                atype = aa[0]; 

                if (atype == 'L')
                {
                    return; 
                }
                if (atype == 'D')
                {
                    alength = 8;
                }
                if (atype == 'C')
                {
                    if (Byte.TryParse(aa.Substring(1, aa.Length - 1), out alength)) //Get the last two elements of string and convert to type byte
                    {
                        return;
                    }
                }
                if (atype == 'N')
                {
                    jpos = aa.IndexOf('.'); 

                    if (jpos < 0) // if '.' isn't found in string
                    {
                        if (byte.TryParse(aa.Substring(1, aa.Length - 1), out alength))
                        {
                            adecimals = 0;
                            return; 
                        }
                    }
                    else
                    {
                        if ((byte.TryParse(aa.Substring(2, jpos - 2), out alength)) && (byte.TryParse(aa.Substring(jpos + 1 ,aa.Length - jpos), out adecimals)))
                        {
                            return;
                        }
                    }
                    return;
                }
            }    
        }

Я проверил это, дав ему строку вроде:

string test = "Okay:C15"
TestingThis(test)

Хотя я в замешательстве. В коде Delphi только один параметр является входным: astring, а остальные якобы возвращаемые значения? Как это возможно? Я ничего не видел о входе одного параметра и выходе 4 Из того, что я прочитал, ключевое слово var означает, что они передаются по ссылке, что означает, что я должен использовать ref в версии С#. Сама функция предположительно вызывается только один раз, а ввод на самом деле представляет собой одну строку.

Изменить: изменил мою функцию на это:

public static void TestingThis(string astring, out string aname, out char atype, out byte alength, out byte adecimals)

И я называю это так:

    string test = "Okay:C15";
    string aname;
    char atype;
    byte alength;
    byte adecimals;
    TestingThis(test, out aname, out atype, out alength, out adecimals);

Это правильное преобразование из Delphi в C#?


person pfinferno    schedule 19.02.2016    source источник
comment
var - это ключевое слово в C#, которое implicitly vs explicitly сообщает вам, что такое тип переменной.. также вы можете вернуть столько значений из метода, если сигнатура метода имеет параметр out, например, var myVar = new DataTable это то же самое, что сказать явно DataTable myVar = new DataTable() и передать по ref в С# вам все равно нужно будет указать ключевое слово ref в сигнатуре метода, а также выполнить поиск в Google по C# MSDN var, а также, если вы ожидаете вернуть значение из вашего метода С#, который вы опубликовали, вам нужно изменить void к фактическому типу данных   -  person MethodMan    schedule 19.02.2016
comment
var находится в части delphi, которую я собирался переключить на ref в C#, поскольку я читал, что это ее аналог. Итак, для всех параметров, перечисленных как var в delphi, которые должны быть возвращаемыми параметрами, будет ли эквивалент C# out ref paramName ? Редактировать: N/m так не работает. Хм.   -  person pfinferno    schedule 19.02.2016
comment
было бы просто out взглянуть на этот отличный пост/объяснение - stackoverflow.com/questions/1516876/when-to-use-ref-vs-out Я также знаю, что Delphi исключительно хорошо кодировал его в течение 17 из моих 22 лет кодирования.   -  person MethodMan    schedule 19.02.2016
comment
Хм, так в Delphi вам не нужно инициализировать параметры и помещать их в вызов, чтобы получить для них значения? Например, я нигде не вижу никаких других параметров, только входную строку для функции. Однако я не могу сделать это на С#, похоже, мне нужно сначала инициализировать и поместить их в качестве параметров.   -  person pfinferno    schedule 19.02.2016
comment
это правильно delphi, вам не нужно инициализировать параметры, но C # .net вы делаете особенно те, которые вы будете использовать в качестве выходных параметров.   -  person MethodMan    schedule 19.02.2016
comment
Спасибо. Последний вопрос, в вашем первом сообщении говорилось, что нужно использовать ref, чтобы обойти ref в C#, но скажите, что просто используйте out в следующем. Что правильно? Я собираюсь отредактировать свой основной пост с тем, что у меня есть сейчас.   -  person pfinferno    schedule 19.02.2016
comment
если вы хотите вернуть несколько значений в методе, который не является ссылкой, например, если вы вызываете метод и хотите вернуть чей-то возраст.. зачем вам менять возраст на возраст возвращаемых значений, используя ключевое слово ref, когда все вам нужно использовать простой параметр вывода.. выполните поиск msdn google по параметрам вывода С#, вам нужно понять четкую разницу между ref.. и out.. также, если вы хотите использовать в качестве глобальной переменной, например, вы бы передайте эти значения ref в свой метод. но окна и веб разные.. так что будьте осторожны, когда вы начинаете кодировать чаще в обоих.   -  person MethodMan    schedule 19.02.2016
comment
Ладно, думаю, теперь я понимаю. Не могли бы вы взглянуть на мою последнюю правку?   -  person pfinferno    schedule 19.02.2016
comment
вам все равно нужно инициализировать выходные параметры, либо выполните следующие действия, например, `string aname = string.Empty;`, либо вы можете использовать ключевое слово (по умолчанию), но я предпочитаю string.Empty vs string aname = (default)string; всегда инициализируйте целые числа = 0, объекты = null , строка=строка.Пустой; или какое-то строковое значение. char = ' ' decimals = 0.0 не 0 и т.д.. вы поняли дрейф   -  person MethodMan    schedule 19.02.2016
comment
Теперь вижу, спасибо! Я отмечу как ответ, если вы сделаете один.   -  person pfinferno    schedule 19.02.2016
comment
Рад, что смог пролить на вас больше света..   -  person MethodMan    schedule 19.02.2016


Ответы (1)


Если вы хотите вернуть несколько значений в методе, который не является ссылкой, например, если вы вызываете метод и хотите вернуть чей-то возраст... зачем вам менять возраст на возраст возвращаемых значений, используя ключевое слово ref, когда все вам нужно использовать простой параметр вывода.. выполните поиск msdn google по параметрам вывода С#, вам нужно понять четкую разницу между ref.. и out.. также, если вы хотите использовать в качестве глобальной переменной, например, вы бы передайте эти значения ref в свой метод. но окна и веб разные.. так что будьте осторожны, когда вы начинаете кодировать чаще в обоих

person MethodMan    schedule 19.02.2016