Skip to content

Commit 5a77d20

Browse files
yevhenclaude
andcommitted
Fix CI reflection failures by replacing DynamicInvoke with strongly-typed lambdas
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 6c48d54 commit 5a77d20

4 files changed

Lines changed: 7 additions & 6 deletions

File tree

learnings.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ This document is organized by topic to consolidate key learnings about the proje
126126
- **Cross-Platform Path Handling:** MSBuild path handling differences between Windows/Unix require careful attention to separators and absolute vs relative paths
127127
- **Package Source Discovery:** NuGet source discovery during package testing can fail silently if local feed structure is incorrect - verify with `--verbosity detailed`
128128
- **DateTime Culture-Dependent Formatting:** DateTime.ToString() produces different output across platforms (macOS: "1/1/2023", Linux: "01/01/2023 00:00:00") - use `dt.ToString("M/d/yyyy", CultureInfo.InvariantCulture)` for consistent cross-platform formatting in error messages
129+
- **DynamicInvoke Cross-Platform Issues:** Using `Expression.Lambda(expression).Compile().DynamicInvoke()` can fail on CI/certain runtimes with `NotSupportedException: Specified method is not supported` - use strongly-typed `Expression.Lambda<Func<object>>(Expression.Convert(expression, typeof(object))).Compile()()` for direct invocation without reflection
129130

130131
## String Diffing Implementation (Increment 5)
131132

src/SharpAssert.Runtime/Core/ExpressionAnalyzer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,11 @@ static EvaluationResult AnalyzeMethodCall(MethodCallExpression methodCall, Dicti
152152
{
153153
if (!CompiledCache.TryGetValue(expression, out var compiled))
154154
{
155-
compiled = Expression.Lambda(expression).Compile();
155+
compiled = Expression.Lambda<Func<object>>(Expression.Convert(expression, typeof(object))).Compile();
156156
CompiledCache[expression] = compiled;
157157
}
158158

159-
return compiled.DynamicInvoke();
159+
return ((Func<object>)compiled)();
160160
}
161161

162162
static bool EvaluateBinaryExpression(ExpressionType nodeType, object? leftValue, object? rightValue) => nodeType switch

src/SharpAssert.Runtime/Features/LinqOperations/LinqOperationFormatter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ static string FormatCollection(object? collection)
136136

137137
static object? GetValue(Expression expression)
138138
{
139-
var compiled = Expression.Lambda(expression).Compile();
140-
return compiled.DynamicInvoke();
139+
var lambda = Expression.Lambda<Func<object>>(Expression.Convert(expression, typeof(object)));
140+
return lambda.Compile()();
141141
}
142142

143143
static string GetPredicateString(MethodCallExpression methodCall) =>

src/SharpAssert.Runtime/Features/SequenceEqual/SequenceEqualComparer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ static SequenceDiffLine ToDiffLine(string line, IReadOnlyList<object?> firstValu
171171

172172
static object? GetValue(Expression expression)
173173
{
174-
var compiled = Expression.Lambda(expression).Compile();
175-
return compiled.DynamicInvoke();
174+
var lambda = Expression.Lambda<Func<object>>(Expression.Convert(expression, typeof(object)));
175+
return lambda.Compile()();
176176
}
177177
}

0 commit comments

Comments
 (0)