windows-runtime - 如何构造一个空的 DeviceInformationCollection?
问题描述
我正在实现一个返回DeviceInformationCollection
. 实现可能会超时(或失败),在这种情况下,我想返回一个空集合。这是为了允许接口的客户端总是迭代返回的集合,不管它是否成功,例如
auto&& devices{ co_await MyType::GetDevicesAsync() };
for (auto&& device : devices)
{
// Do crazy stuff with 'device'
}
但是,我不知道如何构造一个空的DeviceInformationCollection
. 以下代码“有效”,但在客户端使用上面的代码时会导致未定义的行为:
IAsyncOperation<DeviceInformationCollection> MyType::GetDevicesAsync()
{
// Doing Guru Meditation
// ...
co_return { nullptr };
}
我目前的解决方法是返回一个IVector<DeviceInformation>
,并在成功时将内部的项目复制DeviceInformationCollection
到向量中。这既乏味又低效。我宁愿按DeviceInformationCollection
原样返回,并在失败时构造一个空集合。
有没有办法做到这一点?
解决方案
正式地,这是不支持的,因为 DeviceInformationCollection 类不提供创建自身空实例的方法。除非您可以在 Windows.Devices.Enumeration API 中找到为您执行此操作的某些函数,否则您将不走运。
非正式地,我们可以观察到 DeviceInformationCollection 类的默认接口是 IVectorView。这意味着这个接口代表了 ABI 上的类。因此,您可以利用这些知识来耍花招,但总的来说,这是非常危险的,因为接受 DeviceInformationCollection 作为输入的 API 可能会假定其实现是独占的,因此依赖于您可能不知道的一些内部布局。最好每次都以多态和安全的方式返回 IVectorView。像这样的东西:
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Devices::Enumeration;
IAsyncOperation<IVectorView<DeviceInformation>> Async()
{
DeviceInformationCollection devices = co_await // ... some async call
if (devices)
{
co_return devices;
}
// Returns empty IVectorView...
co_return single_threaded_observable_vector<DeviceInformation>().GetView();
}
int main()
{
for (auto&& device : Async().get())
{
printf("%ls\n", device.Name().c_str());
}
}
推荐阅读
- python-3.x - Geopy,熊猫,FOR 循环失败
- php - 将字符串数组转换为 Laravel 查询生成器的数组
- rust - 是否可以在 Rust 中一般访问枚举值?
- python - Python - 长时间运行进程的状态(多个进程的可能性)
- python - 在 scipy 的差分进化算法中添加 minimumr_kwargs
- azure - 为什么 Blazor 应用程序中的 XML 验证会在 localhost 和 Azure 静态 Web 应用程序上提供不同的消息?
- hyperlink - 我想创建一个带有多个 pdf 链接的 whatsapp 共享链接,该链接在消息上显示单个单词的超链接
- c++ - 如何在 C++ 中使用模板参数作为参数覆盖方法?
- google-apps-script - 将单元格复制到另一个工作表的脚本,例如,基于单元格的背景颜色
- javascript - 运行 php 脚本“隐藏”