diff --git a/CodeConverter/CSharp/ExpressionNodeVisitor.cs b/CodeConverter/CSharp/ExpressionNodeVisitor.cs index 7e98971b7..307e882ec 100644 --- a/CodeConverter/CSharp/ExpressionNodeVisitor.cs +++ b/CodeConverter/CSharp/ExpressionNodeVisitor.cs @@ -420,6 +420,12 @@ public override async Task VisitMemberAccessExpression(VBasic. } if (left == null) { left = await node.Expression.AcceptAsync(TriviaConvertingExpressionVisitor); + if (left != null && _semanticModel.GetSymbolInfo(node) is {CandidateReason: CandidateReason.LateBound, CandidateSymbols.Length: 0} + && _semanticModel.GetSymbolInfo(node.Expression).Symbol is {Kind: var expressionSymbolKind} + && expressionSymbolKind != SymbolKind.ErrorType + && _semanticModel.GetOperation(node) is IDynamicMemberReferenceOperation) { + left = SyntaxFactory.ParenthesizedExpression(SyntaxFactory.CastExpression(SyntaxFactory.ParseTypeName("dynamic"), left)); + } } if (left == null) { if (IsSubPartOfConditionalAccess(node)) { diff --git a/Tests/CSharp/ExpressionTests/ExpressionTests.cs b/Tests/CSharp/ExpressionTests/ExpressionTests.cs index 1ff18c0b9..7ceff4eb2 100644 --- a/Tests/CSharp/ExpressionTests/ExpressionTests.cs +++ b/Tests/CSharp/ExpressionTests/ExpressionTests.cs @@ -43,6 +43,43 @@ private void TestMethod(string a) }"); } + [Fact] + public async Task DynamicTestAsync() + { + await TestConversionVisualBasicToCSharpAsync(@" +Public Class C + Public Function IsPointWithinBoundaryBox(ByVal dblLat As Double, dblLon As Double, ByVal boundbox As Object) As Boolean + If boundbox IsNot Nothing Then + Dim boolInLatBounds As Boolean = (dblLat <= boundbox.north) And (dblLat >= boundbox.south) 'Less then highest (northmost) lat, AND more than lowest (southmost) lat + Dim boolInLonBounds As Boolean = (dblLon >= boundbox.west) And (dblLon <= boundbox.east) 'More than lowest (westmost) lat, AND less than highest (eastmost) lon + Return boolInLatBounds And boolInLonBounds + Else + 'Throw New Exception(""boundbox is null."") + End If + Return False + End Function +End Class +", @"using Microsoft.VisualBasic.CompilerServices; // Install-Package Microsoft.VisualBasic + +public partial class C +{ + public bool IsPointWithinBoundaryBox(double dblLat, double dblLon, object boundbox) + { + if (boundbox is not null) + { + bool boolInLatBounds = Conversions.ToBoolean(Operators.AndObject(Operators.ConditionalCompareObjectLessEqual(dblLat, ((dynamic)boundbox).north, false), Operators.ConditionalCompareObjectGreaterEqual(dblLat, ((dynamic)boundbox).south, false))); // Less then highest (northmost) lat, AND more than lowest (southmost) lat + bool boolInLonBounds = Conversions.ToBoolean(Operators.AndObject(Operators.ConditionalCompareObjectGreaterEqual(dblLon, ((dynamic)boundbox).west, false), Operators.ConditionalCompareObjectLessEqual(dblLon, ((dynamic)boundbox).east, false))); // More than lowest (westmost) lat, AND less than highest (eastmost) lon + return boolInLatBounds & boolInLonBounds; + } + else + { + // Throw New Exception(""boundbox is null."") + } + return false; + } +}"); + } + [Fact] public async Task ConversionOfNotUsesParensIfNeededAsync() { diff --git a/Tests/CSharp/StandaloneStatementTests.cs b/Tests/CSharp/StandaloneStatementTests.cs index 9e580a458..2f24ca6cf 100644 --- a/Tests/CSharp/StandaloneStatementTests.cs +++ b/Tests/CSharp/StandaloneStatementTests.cs @@ -135,12 +135,12 @@ End If var cmccIds = new List(); foreach (var scr in _sponsorPayment.SponsorClaimRevisions) { - foreach (var claim in (IEnumerable)scr.Claims) + foreach (var claim in (IEnumerable)((dynamic)scr).Claims) { - if (claim.ClaimSummary is ClaimSummary) + if (((dynamic)claim).ClaimSummary is ClaimSummary) { { - var withBlock = (ClaimSummary)claim.ClaimSummary; + var withBlock = (ClaimSummary)((dynamic)claim).ClaimSummary; cmccIds.AddRange(withBlock.UnpaidClaimMealCountCalculationsIds); } } @@ -151,9 +151,8 @@ End If 2 source compilation errors: BC30451: '_sponsorPayment' is not declared. It may be inaccessible due to its protection level. BC30002: Type 'ClaimSummary' is not defined. -3 target compilation errors: +2 target compilation errors: CS0103: The name '_sponsorPayment' does not exist in the current context -CS1061: 'object' does not contain a definition for 'ClaimSummary' and no accessible extension method 'ClaimSummary' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?) CS0246: The type or namespace name 'ClaimSummary' could not be found (are you missing a using directive or an assembly reference?)"); } } \ No newline at end of file