Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 17, 2025

Summary

Documents the .NET 10 behavioral change where casting COM objects implementing IDispatchEx to IReflect now fails instead of succeeding with unusable members.

Changes:

  • Created breaking change article at docs/core/compatibility/interop/10.0/idispatchex-ireflect-cast.md
  • Updated TOC and index files to include the new article

Previous behavior (.NET 5-9):

var file = Activator.CreateInstance(Type.GetTypeFromProgID("htmlfile"));
Console.WriteLine(file is IReflect ? "supported" : "NOT supported");
// Prints "supported" (but all IReflect members threw TypeLoadException)

New behavior (.NET 10):

var file = Activator.CreateInstance(Type.GetTypeFromProgID("htmlfile"));
Console.WriteLine(file is IReflect ? "supported" : "NOT supported");
// Prints "NOT supported"

Recommended migration:

Console.WriteLine(file is IDispatchEx ? "supported" : "NOT supported");

[ComImport]
[Guid("A6EF9860-C720-11D0-9337-00A0C90DCAA9")]
interface IDispatchEx { }

Fixes #49921

Original prompt

This section details on the original issue you should resolve

<issue_title>[Breaking change]: Casting COM object that implements IDispatchEx to IReflect now fails</issue_title>
<issue_description>### Description

Since .NET 5, the ability to cast a COM object that implements IDispatchEx to IReflect has been possible. However, all members on that IReflect instance would throw TypeLoadException. In .NET 10 this behavior changed so that the cast will fail.

Version

.NET 10 RC 1

Previous behavior

Casting a COM object that implements IDispatchEx to IReflect would succeed.

using System.Reflection;
var file = Activator.CreateInstance(Type.GetTypeFromProgID("htmlfile"));
Console.WriteLine("IReflect is " + (file is IReflect ? "supported" : "NOT supported"));
// Prints "IReflect is supported"

New behavior

Casting a COM object that implements IDispatchEx to IReflect will now fail.

using System.Reflection;
var file = Activator.CreateInstance(Type.GetTypeFromProgID("htmlfile"));
Console.WriteLine("IReflect is " + (file is IReflect ? "supported" : "NOT supported"));
// Prints "IReflect is NOT supported"

Type of breaking change

  • Binary incompatible: Existing binaries might encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
  • Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code might require source changes to compile successfully.
  • Behavioral change: Existing binaries might behave differently at run time.

Reason for change

This was removed since all members on the resulting IReflect instance would be unusable. The TypeLoadException exception that would result from accessing any of the members mentioned a type that was never included in .NET Core and was therefore confusing and unhelpful as to the underlying issue. Removal of the cast behavior was therefore deemed appropriate.

Recommended action

The only viable question that could be asked in .NET 5+ with this cast was, "Does the type implement IDispatchEx?" In this case, the better way to ask that question is as follows:

var file = Activator.CreateInstance(Type.GetTypeFromProgID("htmlfile"));
Console.WriteLine("IDispatchEx is " + (file is IDispatchEx ? "supported" : "NOT supported")); 

[ComImport]
[Guid("A6EF9860-C720-11D0-9337-00A0C90DCAA9")]
interface IDispatchEx { }

Feature area

Interop

Affected APIs

This doesn't impact any specific .NET API.</issue_description>

Comments on the Issue (you are @copilot in this section)

@AaronRobinsonMSFT /cc @davidwrighton @jkotas @ClearScriptLib @AaronRobinsonMSFT /cc @dotnet/interop-contrib @AaronRobinsonMSFT > Why will `file is IReflect` throw; shouldn't it return `false`?

Updated.</comment_new>


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.


Internal previews

📄 File 🔗 Preview link
docs/core/compatibility/10.0.md Breaking changes in .NET 10
docs/core/compatibility/interop/10.0/idispatchex-ireflect-cast.md Casting COM object that implements IDispatchEx to IReflect fails
docs/core/compatibility/toc.yml docs/core/compatibility/toc

Copilot AI changed the title [WIP] Fix casting COM object to IReflect in .NET 10 Add breaking change documentation for IDispatchEx to IReflect cast failure in .NET 10 Nov 17, 2025
Copilot AI requested a review from gewarren November 17, 2025 17:01
Copilot finished work on behalf of gewarren November 17, 2025 17:01
@gewarren gewarren marked this pull request as ready for review November 17, 2025 17:20
@gewarren gewarren requested a review from a team as a code owner November 17, 2025 17:20
Copilot AI review requested due to automatic review settings November 17, 2025 17:20
@gewarren gewarren marked this pull request as draft November 17, 2025 17:20
Copilot finished reviewing on behalf of gewarren November 17, 2025 17:22
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR documents a .NET 10 breaking change where casting COM objects implementing IDispatchEx to IReflect now fails instead of succeeding with unusable members.

  • Adds comprehensive breaking change documentation explaining the behavioral change, reason, and recommended migration path
  • Updates TOC and index files to include the new article in the interop section
  • Provides clear before/after code examples demonstrating the behavior change

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
docs/core/compatibility/interop/10.0/idispatchex-ireflect-cast.md New breaking change article documenting the IDispatchEx to IReflect cast failure in .NET 10 with code examples and migration guidance
docs/core/compatibility/toc.yml Adds TOC entry for the new breaking change article in the Interop section
docs/core/compatibility/10.0.md Adds index entry for the new breaking change in the Interop category

@gewarren gewarren marked this pull request as ready for review November 19, 2025 20:43
@gewarren gewarren enabled auto-merge (squash) November 19, 2025 20:43
@gewarren gewarren merged commit 51aae93 into main Nov 19, 2025
11 checks passed
@gewarren gewarren deleted the copilot/fix-com-object-casting branch November 19, 2025 21:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Breaking change]: Casting COM object that implements IDispatchEx to IReflect now fails

3 participants