Skip to content

Commit 18f8528

Browse files
Fix CS0206 when converting ReDim Preserve on a property
When `ReDim Preserve` is used on a property in VB.NET, the C# converter was generating `Array.Resize(ref Property, ...)` which causes CS0206 because properties cannot be passed as `ref` or `out`. This change updates `MethodBodyExecutableStatementVisitor.cs` to detect when the target of `ReDim Preserve` is a property or member access. In such cases, it generates a temporary variable, assigns the property value to it, resizes the temporary variable using `ref`, and then assigns the temporary variable back to the property. Example: VB.NET: ```vb Public Property NumArray1 As Integer() ... ReDim Preserve NumArray1(4) ``` Converted C#: ```csharp var argNumArray1 = NumArray1; Array.Resize(ref argNumArray1, 5); NumArray1 = argNumArray1; ``` This ensures valid C# code is generated. Co-authored-by: GrahamTheCoder <2490482+GrahamTheCoder@users.noreply.github.com>
1 parent 4235dd7 commit 18f8528

2 files changed

Lines changed: 41 additions & 0 deletions

File tree

CodeConverter/CSharp/MethodBodyExecutableStatementVisitor.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,14 @@ private async Task<SyntaxList<StatementSyntax>> ConvertRedimClauseAsync(VBSyntax
320320
var csTargetArrayExpression = await node.Expression.AcceptAsync<ExpressionSyntax>(_expressionVisitor);
321321
var convertedBounds = (await CommonConversions.ConvertArrayBoundsAsync(node.ArrayBounds)).Sizes.ToList();
322322
if (preserve && convertedBounds.Count == 1) {
323+
if (node.Expression is VBSyntax.MemberAccessExpressionSyntax || node.Expression is VBSyntax.IdentifierNameSyntax identifier && _semanticModel.GetSymbolInfo(identifier).Symbol.IsKind(SymbolKind.Property)) {
324+
var (tempVarDecl, tempVar) = CreateLocalVariableWithUniqueName(node.Expression, "arg" + csTargetArrayExpression.ToString().Split('.').Last(), csTargetArrayExpression);
325+
var resizeArgs = new[] { (ExpressionSyntax)tempVar, convertedBounds.Single() }.CreateCsArgList(SyntaxKind.RefKeyword);
326+
var resizeCall = SyntaxFactory.InvocationExpression(ValidSyntaxFactory.MemberAccess(nameof(Array), nameof(Array.Resize)), resizeArgs);
327+
var assignment = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, csTargetArrayExpression, tempVar);
328+
return SyntaxFactory.List(new StatementSyntax[] { tempVarDecl, SyntaxFactory.ExpressionStatement(resizeCall), SyntaxFactory.ExpressionStatement(assignment) });
329+
}
330+
323331
var argumentList = new[] { csTargetArrayExpression, convertedBounds.Single() }.CreateCsArgList(SyntaxKind.RefKeyword);
324332
var arrayResize = SyntaxFactory.InvocationExpression(ValidSyntaxFactory.MemberAccess(nameof(Array), nameof(Array.Resize)), argumentList);
325333
return SingleStatement(arrayResize);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System.Threading.Tasks;
2+
using ICSharpCode.CodeConverter.Tests.TestRunners;
3+
using Xunit;
4+
5+
namespace ICSharpCode.CodeConverter.Tests.CSharp.StatementTests;
6+
7+
public class RedimPreserveTests : ConverterTestBase
8+
{
9+
[Fact]
10+
public async Task RedimPreserveOnPropertyAsync()
11+
{
12+
await TestConversionVisualBasicToCSharpAsync(
13+
@"Public Class TestClass
14+
Public Property NumArray1 As Integer()
15+
16+
Public Sub New()
17+
ReDim Preserve NumArray1(4)
18+
End Sub
19+
End Class", @"using System;
20+
21+
public partial class TestClass
22+
{
23+
public int[] NumArray1 { get; set; }
24+
25+
public TestClass()
26+
{
27+
var argNumArray1 = NumArray1;
28+
Array.Resize(ref argNumArray1, 5);
29+
NumArray1 = argNumArray1;
30+
}
31+
}");
32+
}
33+
}

0 commit comments

Comments
 (0)