Description
From what I recall, IDynamicInterfaceCastable.IsInterfaceImplemented is meant to be a per instance decision rather than a per type thing. GetInterfaceImplementation was the one that was a per type decision. But it seems the results of IsInterfaceImplemented are being cached based on type. In the below repro, which is similar to our IInspectable in CsWinRT, we are seeing that if an is check passes for one instance of a type, it also passes for other instances even if the IDIC implementation is returning false.
This issue seems to only happen on AOT for generic interfaces. On JIT, the expected results are observed.
Reproduction Steps
internal class Program
{
static void Main(string[] args)
{
var shapeshifter = new Shapeshifter(true);
bool isEnumerableInt = shapeshifter is IEnumerable<int>;
Console.WriteLine("shapeshifter is IEnumerable<int>: " + isEnumerableInt);
var shapeshifter2 = new Shapeshifter(false);
bool isEnumerableInt2 = shapeshifter2 is IEnumerable<int>;
Console.WriteLine("shapeshifter2 is IEnumerable<int>: " + isEnumerableInt2);
}
}
class Shapeshifter : IDynamicInterfaceCastable
{
private bool _result;
public Shapeshifter(bool result)
{
_result = result;
}
public RuntimeTypeHandle GetInterfaceImplementation(RuntimeTypeHandle interfaceType) => throw new NotImplementedException();
public bool IsInterfaceImplemented(RuntimeTypeHandle interfaceType, bool throwIfNotImplemented) => _result;
}
Expected behavior
Same as .NET 8 AOT and same as .NET 10 JIT
net8.0\publish\win-x64\ConsoleApp35.exe
shapeshifter is IEnumerable: True
shapeshifter2 is IEnumerable: False
Actual behavior
net10.0\publish\win-x64\ConsoleApp35.exe
shapeshifter is IEnumerable: True
shapeshifter2 is IEnumerable: True
Regression?
.NET 8, seems related to #108328
Known Workarounds
No response
Configuration
.NET 10
Other information
No response
Description
From what I recall,
IDynamicInterfaceCastable.IsInterfaceImplementedis meant to be a per instance decision rather than a per type thing.GetInterfaceImplementationwas the one that was a per type decision. But it seems the results ofIsInterfaceImplementedare being cached based on type. In the below repro, which is similar to ourIInspectablein CsWinRT, we are seeing that if anischeck passes for one instance of a type, it also passes for other instances even if the IDIC implementation is returning false.This issue seems to only happen on AOT for generic interfaces. On JIT, the expected results are observed.
Reproduction Steps
Expected behavior
Same as .NET 8 AOT and same as .NET 10 JIT
net8.0\publish\win-x64\ConsoleApp35.exe
shapeshifter is IEnumerable: True
shapeshifter2 is IEnumerable: False
Actual behavior
net10.0\publish\win-x64\ConsoleApp35.exe
shapeshifter is IEnumerable: True
shapeshifter2 is IEnumerable: True
Regression?
.NET 8, seems related to #108328
Known Workarounds
No response
Configuration
.NET 10
Other information
No response