The following code iterates through a set of processors and returns their ids. Hardware exploration is hazardous and I want to make this function is as stable as possible.
That is:
- If an exception was thrown whilst preparing the iteration, return a null reference; and
- If an exception was thrown during an iteration, simply skip this iteration, silently.
Code:
Public ReadOnly Iterator Property ProcessorIds As IEnumerable(Of String) Implements IHardwareIds.ProcessorIds
Get
Try
Dim BiosQuery As ObjectQuery = New SelectQuery("Win32_Processor") 'https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-processor
Dim HardwarePieces As New ManagementObjectSearcher(BiosQuery)
For Each MyInfo As ManagementObject In HardwarePieces.Get
Try
Dim ProcessorId As String = MyInfo("ProcessorId").ToString
Yield ProcessorId
Catch ex As Exception
End Try
Next
Catch ex As Exception
Return Nothing
End Try
End Get
End Property
The current code does not compile because using return in an iterator is forbidden.
The best I could think of was to replace Return Nothing by Yield Nothing. I expect it should result in an enumerable containing one item, which is a null reference. Is this my only option?
I know I could just use a regular function and return the collection once fully iterated. This is an exercise to practice with Iterators.
I don't see a way to cause an
Iteratorto return an empty collection upon exception, if that is what you really want to do. If you do, you could stop usingIteratorandYield, and simply doUsing LINQ without the
Iteratoractually allows you to remove theFor Eachand simplify the code.(If you would rather return null, it's almost the same)
however, returning null has a different feel that other Enumerable functions (such as
Where, which returns an empty collection when the predicate is not satisfied by any element, as pointed out by @Anu6is).You can also stop iteration upon the first exception. If
Yieldis never hit, your result is an empty collection. I think this is more in the spirit ofIterator.The C# analog is yield break; and it seems quite clean. See also this answer.