2016-07-22 2 views
4

У меня есть этот код VBC# альтернатива код VB

Try 
    For i = 0 To OutData.NumMerids - 1 
     With OutData.MeridData(0) 
      .NumCurves = InStepFiveData.ConvexSurfaceData.MultiCurveData.NumOzCurves + InStepFiveData.ConvexSurfaceData.MultiCurveData.NumLenticularCurves 
      ReDim .CurveData(.NumCurves - 1) 
     End With 
    Next 
    ... 

Я хочу создать подобные C# код. Я использовал некоторую логику и вычитал код ниже.

try 
{ 
    for (i = 0; i <= OutData.NumMerids - 1; i++) 
    { 
     // var _with25 = OutData.MeridData[0]; 
     OutData.MeridData[0].NumCurves =(short) (InStepFiveData.ConvexSurfaceData.MultiCurveData.NumOzCurves + InStepFiveData.ConvexSurfaceData.MultiCurveData.NumLenticularCurves); 
     // ERROR: Not supported in C#: ReDimStatement 
     Array.Resize(ref OutData.MeridData[0].CurveData, OutData.MeridData[0].NumCurves - 1); 
    } 
    ... 
} 

Просто хотите знать, что я делаю что-то неправильно?

Благодаря

+2

Пожалуйста, обратите внимание на размещение этого кода в обзоре кода. http://codereview.stackexchange.com/ – Maverick

+0

Имейте в виду, что, хотя Array.Resize' просто изменяет размер вашего массива, он фактически создает копию за кулисами, эффективно меняя ссылку на ваш массив. в этом случае это означает, что если вы ранее присвоили 'OutData.MeridData [0] .CurveData' какой-либо другой переменной, он все равно будет указывать на массив без изменения размера. – Ash

+1

Не вычитайте 1 в своем вызове 'Resize'. Размеры массива C# и большинство функций фрейма работают в терминах * lengths *, объявления массива VB работают в терминах * границ *. Обычно это означает, что сопоставимый код между C# и VB с участием массивов, когда хотя бы один из них использует языковые конструкции (а не библиотечные функции), требует корректировки значения на единицу. –

ответ

2

Ошибка заключается в утверждении Array.Resize; более конкретно, в указанном размере.

В VB.Net вы указываете последний индекс массива, где в C# вы указываете длину массива
Итак, есть сдвиг 1 между ними.

ReDim .CurveData(.NumCurves - 1) 
' equivalent to 
ReDim .CurveData(0 To .NumCurves - 1) ' length is (.NumCurves - 1) - 0 + 1 = .NumCurves 

Это происходит из-за того, что в VB6, вы могли бы массив индексируется в другой базе, чем 0 (в частности 1 индексируются сбора) и так, чтобы было действительным (не в VB.Net)

Dim someArray(-4 To 5) As Integer ' declares an array of 10 integer indexed from -4 to 5 

Назад к коду нужно просто дать размер

//Array.Resize(ref OutData.MeridData[0].CurveData, OutData.MeridData[0].NumCurves - 1); 
// replaced by 
Array.Resize(ref OutData.MeridData[0].CurveData, OutData.MeridData[0].NumCurves); 

Что касается комментария, данного Ашвином Наиром; ReDim имеет такое же поведение (я не был бы сюрприз ReDim использует Array.Resize внутренне в .NET)

Edit:

Как сказал Дэйв в это answer Array.Resize является перевод Redim Preserve не Redim (который стирает данные далеко)

+0

так мне нужно, чтобы он везде, где я вижу объявление массива? – Apoorv

+0

@Apoorv Скорее всего, да, возможно, вы будете нужно это для каждого объявления массива 'Dim', изменить размер' ReDim' или скопировать 'ReDim Preserve', это та же логика для цикла' for', в VB.Net вам нужно поставить 'bound-1', когда на C# вы можете juste put ' Sehnsucht

+0

Вы вводите в заблуждение« ReDim »с« ReDim Preserve ». –

2

Вы (и принятый ответ) путаете «ReDim» с «ReDim Preserve». Вашего утверждение «Redim» просто преобразуется с помощью «нового» оператора для создания массива:

OutData.MeridData[0].CurveData = new Foo[OutData.MeridData[0].NumCurves]; 

(типа «CurveData» мне неизвестен, так что я использовал «Foo» - вы будете иметь заменить соответствующим типом).

1

Несколько вещей, которые вы можете исправить/улучшить:

C# for петли требуют, чтобы объявить переменную цикла.

for(var i = 0; i < 100; i++) {

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

В качестве заменителя для VB-х With Я хотел бы использовать локальную переменную. (Я считаю, что это то, что With действительно делает за кулисами.) Похоже, вы почему-то прокомментировали это. Каждый раз, когда вы ссылаетесь на OutData.MeridData[0] или InStepFiveData.ConvexSurfaceData.MultiCurveData, вам нужно почтить несколько объектов и в зависимости от структуры этих объектов, которые могут быть неэффективными.Плюс это трудно читать.

@Dave Doknjas получил замену Redim справа, вам просто нужно использовать конструктор. Redim фактически выбрасывает старый массив и создает новый, поэтому его имя на самом деле немного вводит в заблуждение. Для использования Redim Preserve вам необходимо использовать Array.Copy для перемещения значений из старого массива в новый.

try { 
    for (var i = 0; i <= OutData.NumMerids - 1; i++) { 
     var meridData = OutData.MeridData[0]; 
     var curveData = InStepFiveData.ConvexSurfaceData.MultiCurveData; 
     meridData.NumCurves = (short)(curveData.NumOzCurves + curveData.NumLenticularCurves); 
     meridData.CurveData = new Foo[meridData.NumCurves]; 
    } 
} 
+0

Что использовать вместо Redim? Я использую Array.Reize(). – Apoorv

+1

. NET-массивы на самом деле не могут быть изменены, поэтому любая функция, которая выглядит как ее изменение размера одного на самом деле создает новый массив и, возможно, копирует содержимое исходного массива. Я просто вручную создаю новый массив самостоятельно. 'new MyClass [100]' – JamesFaix

Смежные вопросы