ARTICLE AD BOX
This question is about style and efficiency. I have a working solution to my problem, but I am searching for a nicer one. I have an array of file paths and I want to find their common parent folder. In case the files are not located in the same folder, I want to throw an exception and terminate the application. So my idea was to use the SingeOrDefault LINQ operator. This operator throws an exception if the sequence contains more than one elements. The exception message is too generic though, and I want to throw a more descriptive one. So I did this:
static string GetCommonParentDirectory(string[] filePaths) { try { return filePaths .Select(p => Path.GetDirectoryName(p)) .Distinct(StringComparer.OrdinalIgnoreCase) .SingleOrDefault(); } catch (InvalidOperationException) // Sequence contains more than one element. { throw new ArgumentException( "The files are not located in the same folder."); } }This works, but it's ugly and relies on catching exceptions, which is not efficient. I would prefer an implementation without try/catch. I am thinking about combining the LINQ operators FirstOrDefault and SingleOrDefault, like this:
static string GetCommonParentDirectory(string[] filePaths) { string commonDirectory = filePaths .Select(p => Path.GetDirectoryName(p)) .Distinct(StringComparer.OrdinalIgnoreCase) .FirstOrDefault(out bool isSingle); if (!isSingle) throw new ArgumentException( "The files are not all located in the same folder."); return commonDirectory; }My question is: How can I implement a FirstOrDefault overload that includes an additional out bool isSingle parameter?
In case the sequence is empty the FirstOrDefault should return null (or default in general), and the value of isSingle should be false. Otherwise the FirstOrDefault should return the first element, and the isSingle should be true only if the sequence contains exactly one element.
I apologize if this question has been asked before. I searched and didn't find any.
Clarification: I am interested for a LINQ operator that has this signature:
public static TSource FirstOrDefault<TSource>( this IEnumerable<TSource> source, out bool isSingle)