如何构造一个空的 DeviceInformationCollection?
How to construct an empty DeviceInformationCollection?
我正在实现一个 return 是 DeviceInformationCollection
的接口。实现可能会超时(或失败),在这种情况下我想 return 一个空集合。这是为了允许接口的客户端始终迭代 returned 集合,无论它是否成功,例如
auto&& devices{ co_await MyType::GetDevicesAsync() };
for (auto&& device : devices)
{
// Do crazy stuff with 'device'
}
但是,我不知道如何构造一个空 DeviceInformationCollection
。以下代码 'works',但当客户端使用上面的代码时会导致未定义的行为:
IAsyncOperation<DeviceInformationCollection> MyType::GetDevicesAsync()
{
// Doing Guru Meditation
// ...
co_return { nullptr };
}
我目前的解决方法是 return 一个 IVector<DeviceInformation>
代替,并在成功时将内部 DeviceInformationCollection
的项目复制到向量中。这既乏味又低效。我宁愿按原样 return DeviceInformationCollection
,并在失败时构建一个空集合。
有办法吗?
正式来说,这不受支持,因为 DeviceInformationCollection class 不提供创建自身空实例的方法。除非你能在 Windows.Devices.Enumeration API 中找到为你执行此操作的函数,否则你就不走运了。
非正式地,我们可以观察到 DeviceInformationCollection class 的默认界面是 IVectorView。这意味着这个接口代表了 ABI 上的 class。因此,您可以利用这些知识玩一些把戏,但总的来说,这是非常危险的,因为接受 DeviceInformationCollection 作为输入的 APIs 可能会假定其实现是排他的,因此依赖于您可能不知道的某些内部布局.最好每次都以多态和安全的方式 return 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());
}
}
我正在实现一个 return 是 DeviceInformationCollection
的接口。实现可能会超时(或失败),在这种情况下我想 return 一个空集合。这是为了允许接口的客户端始终迭代 returned 集合,无论它是否成功,例如
auto&& devices{ co_await MyType::GetDevicesAsync() };
for (auto&& device : devices)
{
// Do crazy stuff with 'device'
}
但是,我不知道如何构造一个空 DeviceInformationCollection
。以下代码 'works',但当客户端使用上面的代码时会导致未定义的行为:
IAsyncOperation<DeviceInformationCollection> MyType::GetDevicesAsync()
{
// Doing Guru Meditation
// ...
co_return { nullptr };
}
我目前的解决方法是 return 一个 IVector<DeviceInformation>
代替,并在成功时将内部 DeviceInformationCollection
的项目复制到向量中。这既乏味又低效。我宁愿按原样 return DeviceInformationCollection
,并在失败时构建一个空集合。
有办法吗?
正式来说,这不受支持,因为 DeviceInformationCollection class 不提供创建自身空实例的方法。除非你能在 Windows.Devices.Enumeration API 中找到为你执行此操作的函数,否则你就不走运了。
非正式地,我们可以观察到 DeviceInformationCollection class 的默认界面是 IVectorView。这意味着这个接口代表了 ABI 上的 class。因此,您可以利用这些知识玩一些把戏,但总的来说,这是非常危险的,因为接受 DeviceInformationCollection 作为输入的 APIs 可能会假定其实现是排他的,因此依赖于您可能不知道的某些内部布局.最好每次都以多态和安全的方式 return 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());
}
}