Skip to content

#62 step 1: the replaceable Dynamitey uses, replaced - #72

Merged
jbtule merged 2 commits into
masterfrom
dynamitey-step1
Sep 22, 2026
Merged

jbtule merged 2 commits into
masterfrom
dynamitey-step1

Conversation

@jbtule

@jbtule jbtule commented Sep 22, 2026

Copy link
Copy Markdown
Member

Step 1 of #62 — a minor-release step, no behaviour change. Three of the five uses go; the two that remain are the type-identity ones the major exists for.

use was now
Dynamic.InvokeConstructor (ActLikeMaker.cs:60) Dynamitey DynamicConstructor.Invoke
Dynamic.GenericDelegateType (ActLikeMaker.cs:1708) Dynamitey local Func/Action tables
String_OR_InvokeMemberName (BinderHash.cs) Dynamitey file deleted
IEquivalentType / AggreType (ActLikeProxy.cs) — unchanged, step 2
InvokeContext (Util.cs) — unchanged, step 2

ActLikeMaker no longer imports Dynamitey at all.

The constructor

DynamicConstructor builds a call site from Binder.InvokeConstructor and caches it per (type, argument count) — the shape is what a site is compiled for, the arguments' runtime types are what it dispatches on. So Create<TTarget, TInterface>(params object[]) still picks the constructor the same way C#'s new T(dynamicArg) does.

Deliberately not Activator.CreateInstance: its overload resolution is not the same, and the suite already pins a case where the two differ (SingleMethodInvoke.cs:198). The value-type parameterless case keeps the Activator path, because a dynamic invocation does not see that constructor — the same carve-out Dynamitey has.

The delegate tables

GenericDelegateType was a lookup into two static arrays of open Func/Action types. It is now the same lookup, locally, with the same arity rules and the same exceptions past them. Only arities under 16 reach it; GenerateFullDelegate already covers the rest.

A correction to #62

That issue lists BinderHash.cs as public API, and therefore a breaking change to remove. It is not — BinderHash, GenericBinderHashBase and BareBonesList are all internal. So deleting them is neither breaking nor something to defer to the major, and both files are gone here. I will correct the issue.

Verified: 190 tests on net8.0 and net10.0, 196 on net47, 101 on browser-wasm; CI=true solution build clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_016mwfq4oeZW8SiD4HjTHYdg

Three of the five go; what is left is the two that cannot be
reimplemented, only matched or dropped, which is what the major is for.

- Dynamic.InvokeConstructor becomes DynamicConstructor.Invoke: a call
  site built from Binder.InvokeConstructor and cached per (type,
  argument count), so the constructor is still chosen by the arguments'
  runtime types. Not Activator.CreateInstance, whose overload
  resolution differs - a difference the suite already pins.
- Dynamic.GenericDelegateType becomes a local pair of Func/Action
  tables, same arity rules and the same errors past them.
- BinderHash.cs and BareBonesList.cs are deleted. Nothing referenced
  them. #62 called BinderHash public API and so a break to remove; it is
  internal, so it is neither.

ActLikeMaker no longer imports Dynamitey at all. The remaining coupling
is ActLikeProxy's IEquivalentType/AggreType and Util's InvokeContext,
both type identity.

190 tests on net8.0 and net10.0, 196 on net47, 101 on browser-wasm.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016mwfq4oeZW8SiD4HjTHYdg
It has one caller, Create<TTarget, TInterface>(params object[]), and no
reason to be visible - adding public API in the same change that removes
some for being needless surface was not the intent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016mwfq4oeZW8SiD4HjTHYdg
@jbtule

jbtule commented Sep 22, 2026

Copy link
Copy Markdown
Member Author

Made DynamicConstructor internal — it has exactly one caller, Create<TTarget, TInterface>(params object[]), and adding public API in the same change that removes some for being needless surface was not the intent. Re-verified: solution builds clean under CI=true, 190 on net8.0 and 196 on net47.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Named constructor arguments are not preserved, and replacement paths lack coverage for the claimed behavior.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 2 High severity

Open (2)
What changed in this PR

Replaces removable Dynamitey usage with cached constructor binding and local delegate tables.

Changes:

  • Adds cached DLR-based constructor invocation.
  • Inlines Func/Action delegate lookup.
  • Removes unused internal binder and list helpers.
File Summary and review findings
ImpromptuInterface/​src/​Optimization/​DynamicConstructor.cs Adds cached constructor binding. Critical (1 vote): named InvokeArg metadata is dropped. Nit (1 vote): add coverage for overload, optional/named arguments, and value-type construction.
ImpromptuInterface/​src/​Optimization/​BinderHash.cs Removes unused internal binder hashing code.
ImpromptuInterface/​src/​Optimization/​BareBonesList.cs Removes unused internal list implementation.
ImpromptuInterface/​src/​EmitProxy/​ActLikeMaker.cs Uses the new constructor helper and local delegate tables. Critical (2 votes): named arguments are not preserved. Nit (1 vote): add public-path coverage for dispatch, optional/value-type handling, and caching.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

public TInterface Create<TTarget, TInterface>(params object[] args) where TInterface : class
{
return this.ActLike(Dynamic.InvokeConstructor(typeof(TTarget), args));
return this.ActLike(DynamicConstructor.Invoke(typeof(TTarget), args));
Comment on lines +67 to +70
for (var i = 0; i < count; i++)
{
infos.Add(CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null));
arguments.Add(Expression.ArrayIndex(argsParameter, Expression.Constant(i)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants