Skip to content

Update AV2230: Only use the dynamic keyword when talking to a dynamic object#380

Closed
dennisdoomen wants to merge 1 commit into
developfrom
copilot/pr298-update-av2230
Closed

Update AV2230: Only use the dynamic keyword when talking to a dynamic object#380
dennisdoomen wants to merge 1 commit into
developfrom
copilot/pr298-update-av2230

Conversation

@dennisdoomen
Copy link
Copy Markdown
Owner

This PR updates guideline AV2230.

It was split out of #298 so the change can be reviewed independently.

Files:

  • _rules/2230.md

Part of the replacement for #298.

Split from #298.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread _rules/2230.md
The `dynamic` keyword has been introduced for interop with languages where properties and methods can appear and disappear at runtime. Using it can introduce a serious performance bottleneck, because various compile-time checks (such as overload resolution) need to happen at runtime, again and again on each invocation. You'll get better performance using cached reflection lookups, `Activator.CreateInstance()` or pre-compiled expressions (see [here](https://andrewlock.net/benchmarking-4-reflection-methods-for-calling-a-constructor-in-dotnet/) for examples and benchmark results).

While using `dynamic` may improve code readability, try to avoid it in library code (especially in hot code paths). However, keep things in perspective: we're talking microseconds here, so perhaps you'll gain more by optimizing your SQL statements first.
The `dynamic` keyword has been introduced for interop with languages where properties and methods can appear and disappear at runtime. Using it can introduce a serious performance bottleneck, because various compile-time checks (such as overload resolution) need to happen at runtime. Use it sparingly, and only when you have no other choice.
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.

The original recommendations still hold; see Stephen Toub's performance series. The last sentence may lead a beginner to think there is no other choice, which is almost never true.

I think the changes to this rule should be reverted.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

I don't get your point. Isn't the new version just a shorter version?

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.

My point is that the original version contained important information that was removed:

  • "again and again on each invocation": It's not just a one-time startup cost that users may be unaware of.
  • The original version provided guidance on better alternatives (though slightly outdated; a cached Delegate.CreateDelegate can also be used if all types used in the signature are known at compile-time, as described in Stephen's post)
  • In the new version, it's unclear when someone has no other choice (combined with a lack of alternatives)
  • The removed bullet that puts the perf impact into perspective was removed. Code that rarely executes or is part of a dev-local or CI setup may benefit from cleaner code rather than reflection.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Alright. I don't care about this rule as I never use dynamic, but given your arguments, I'll keep it as-is.

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.

Thanks.

Unfortunately, I have a case where dynamic is heavily used, because it involves generic type substitution. I'd like to get rid of it, but investigating the alternatives takes time and I never get to it. Once I know more, I can probably propose up-to-date guidance for this rule.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Ask your friendly neighborhood AI agent to do it ;-)

@bkoelman bkoelman deleted the copilot/pr298-update-av2230 branch April 3, 2026 14:44
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