5

Is there a neat way to ignore exceptions in Linq? I.e., lets say I have a class ObjectA that takes a string parameter in its constructor, and within the constructor there is some validation going on - meaning that if the string does not have the correct format, the constructor will throw. By the following code I would get a List of ObjectA from a list of strings:

var result = new List<ObjectA>();
foreach (string _s in ListOfFiles) {
    try {
        ObjectA _A = new ObjectA(_s);
        result.Add(_A);
    }
    catch{}
}

So my question is: Is there a one line linq way, a la (pseudocode coming up ...)

var result = ListOfFiles.Select(n => try {new ObjectA(n)}).ToList();
EluciusFTW
  • 2,565
  • 6
  • 42
  • 59
  • 2
    You can do it, as in Felipe's solution (he beat me to it), but I don't think it's a good idea. It can result in poor performance for large collections - exceptions are very expensive - and it's conceptually "dirty" as well... instead, `ObjectA` could expose some method that you could ask whether `n` is a legal value. What if one day an exception is thrown for a different reason - if you gobble all exceptions silently, it will take a while to trace the bug. – Konrad Morawski Feb 14 '14 at 11:10
  • Yes, I agree with you @Konrad Morawski. – Felipe Oriani Feb 14 '14 at 11:18
  • Well, actually it depends. If exception is exceptional situation (i.e. normally you don't have it) then you can use exceptions handling with large collections. But never never never swallow exception if it occurred - either handle and log it or wrap and throw – Sergey Berezovskiy Feb 14 '14 at 11:29
  • @Konrad, yes, having a method to verify that would be possible, but you'd need to construct the instance first to be able to access the method. In my case i want to populate readonly fields, so it'd have to happen in the constructor, I can't construct the empty object, check if it would be valid, then populate – EluciusFTW Feb 14 '14 at 11:46
  • @Sergey, Konrad: ofc I agree that the exception should be dealt with. This piece of code is for a production state, where I want to do things quickly. In the final version I will add a verify method/ exception handling etc. But that was not my question. – EluciusFTW Feb 14 '14 at 11:48
  • @ToaoG the validation could be a static method (it's instance independent, after all), or better still, done by a separate class: `ObjectAValidator` or something. Then you could use one single instance of the validator for all the items. I'm aware this is not what your question was about, that's why I don't post it as an answer, just as a side note, here in comments – Konrad Morawski Feb 14 '14 at 11:59
  • @Konrad: Thanks, sure that would be possible, but would bloat the project. The reason for my question was the contrary, I wanted to do everything in one line ... But in terms of best practice, you're right, of course ;-) – EluciusFTW Feb 14 '14 at 12:44

1 Answers1

4

Considering you are using Linq to objects, you could try using a scope in the Select() method and a Where() to filter the null outputs:

        var result = ListOfFiles.Select(_s =>
            {
                try
                {
                    return new ObjectA(_s);
                }
                catch (Exception)
                {
                    return null;
                }

            }).Where(x => x != null).ToList();

Using strategies like this works fine for linq to objects, but linq to sql does not work as the same because, think for yourself, how would you parse it to SQL? There is simple way to do that.

Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
  • 1
    Didn't know you could put a `try` block in a Linq query. Thanks! – EluciusFTW Feb 14 '14 at 11:51
  • 1
    Actually, you can create a scope using `x => { ... }`, in the scope you can write c# code normally. In linq to sql, it could not work as you want, but in linq to objects, you can do anything you want, but take care with the performance. – Felipe Oriani Feb 14 '14 at 12:02