Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Try-Catch with fluent expressions

This LINQ query expression fails with Win32Exception "Access is denied":

Process.GetProcesses().Select(p => p.MainModule.FileName)

And this fails with IOException "The device is not ready":

DriveInfo.GetDrives().Select(d => d.VolumeLabel)

What is the best way to filter out inaccessible objects and avoid exceptions?

like image 671
Cristian Scutaru Avatar asked Dec 23 '14 03:12

Cristian Scutaru


1 Answers

Write an extension method!

void Main()
{
    var volumeLabels = 
        DriveInfo
        .GetDrives()
        .SelectSafe(dr => dr.VolumeLabel);
}

// Define other methods and classes here

public static class LinqExtensions
{
    public static IEnumerable<T2> SelectSafe<T,T2>(this IEnumerable<T> source, Func<T,T2> selector)
    {
        foreach (var item in source)
        {
            T2 value = default(T2);
            try
            {           
                value = selector(item);
            }
            catch
            {
                continue;
            }
            yield return value;
        }
    }
}

This way you can customise any behaviour you want, and you don't have to create bulky and hacky where clauses, this way you could even get it to return an alternative value if there's an exception.

like image 140
Clint Avatar answered Oct 04 '22 19:10

Clint