Why does the following Desktop UWP (or WinUI or WinRT? I get confused by the terminology) code compile but throw an exception?
var folder = await Windows.Storage.StorageFolder.GetFolderFromPathAsync(@"pathofolder");
var files = await folder.GetFilesAsync(); //IReadOnlyList<Windows.Storage.StorageFile>)
//Exception: Invalid cast from 'WinRT.IInspectable' to 'System.Collections.Generic.IEnumerable`1[Windows.Storage.IStorageFile]'.
var l1 = ((IReadOnlyList<Windows.Storage.IStorageFile>) files).ToList(); //Even crashes if we add e.g. .Select(_=>42) in-between.
Note the cast from StorageFile
to IStorageFile
(a more nasty bug, which is what I had, is a method taking a list of the latter). Is there something wrong with casting to interfaces in this context, or is this a bug? Normally it works fine, e.g. ((IStorageFile) files[0]).Name
.
This only happens when using C#/WinRT on Desktop. Steps to reproduce:
- Download the WinUI 3 Project Templates extension
- Create a new C# "Blank App, Packaged (WinUI in Desktop)" via the template (two projects will be created, one for the code, one for the package)
- Possibly: edit the non-package project file to make sure it lists the correct
TargetFramework
for me it lists net5.0-windows10.0.18362.0
while I only have 10.0.19041.0 installed. I guess I'll report this as a bug in a moment. [Seems to be already reported: GitHub issue]
- Add the following code to e.g.
OnLauched
in App.xaml.cs
:
Task.Run(async () =>
{
try
{
var folder = ApplicationData.Current.LocalFolder;
var files = await folder.GetFilesAsync();
_ = ((IReadOnlyList<IStorageFile>) files).ToList();
}
catch (InvalidCastException ex)
{
Debugger.Break();
}
});
- Run the package project (enabling break on CLR exceptions recommended)
- Observe the
InvalidCastException
in DynamicInterfaceCastableHelpers.IsInterfaceImplemented
question from:
https://stackoverflow.com/questions/65928154/invalid-cast-from-winrt-iinspectable-to-system-collections-generic-ienumerabl 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…