Skip to content

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

@AaronRobinsonMSFT

Description

@AaronRobinsonMSFT

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.


Associated WorkItem - 509623

Metadata

Metadata

Labels

📌 seQUESTeredIdentifies that an issue has been imported into Quest.breaking-changeIndicates a .NET Core breaking change

Type

No type

Projects

Status

🏗 In progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions