3

Today I wrote some code that takes a list of class A instances and creates a list of class B instances using a static factory method:

public abstract class B
{
    public static B CreateB(A a)
    {
        // return a new B instance or null if a B instance can't be created
    }
}

I needed to filter out the nulls so I used LINQ to do both tasks:

var bList = aList.Select(a => B.CreateB(a)).Where(b => b != null).ToList();

Code runs like expected, but I noticed Resharper was suggesting, on the call to CreateB, I should "Convert to method group". I wondered what that means and found some interesting answers on this site. For example: What is a method group in C#? and a comment by Asad to stitty's answer here Filtering Null values in Select (.Select(x => transform(x)) can be .Select(transform))

So I changed my code to:

var bList = aList.Select(B.CreateB).Where(b => b != null).ToList();

This too works as expected, but now I get to my question. Resharper now tells me the Where lambda expression can be removed because b != null "is always true".

I played around and Resharper is correct, but why? Why is there a difference in the returned collection of the Select() when I use a method group? Why does the Select() seem to filter out the nulls out of the collection when I use a method group?

Community
  • 1
  • 1
meir shapiro
  • 647
  • 7
  • 16
  • Just out of curiosity - how does the static method CreateB() 'return a new B instance'? Will it create an inherited class instance? I know it has nothing to do with your question, it's just that I have never seen such a design before (and I'm not an expert, either). – shay__ Jul 16 '15 at 12:13
  • 2
    Are you sure? I just reconstructed your example and I don't get anything about removing the `Where` clause. – Yuval Itzchakov Jul 16 '15 at 12:15
  • @shay__ B is an abstract class and CreateB() returns an instance of an inherited class (or null). – meir shapiro Jul 16 '15 at 12:19
  • @YuvalItzchakov Well, Resharper doesn't say "Remove the Were clause", it says the "Expression is always true" about the b != null check. – meir shapiro Jul 16 '15 at 12:21
  • I understand. But I don't get that either. – Yuval Itzchakov Jul 16 '15 at 12:22
  • @YuvalItzchakov Me too, that's why I posted this question. – meir shapiro Jul 16 '15 at 12:23
  • No I mean, I don't get the ReSharper hint, not the semantics :) Is `A` a reference type? I think we're missing something in your type declaration. Perhaps post your actual types? – Yuval Itzchakov Jul 16 '15 at 12:23
  • Is "a" null too, if an instance of B cannot be created? – mDC Jul 16 '15 at 12:25
  • Yes, A is some custom object I have. B is abstract as I mentioned in an earlier comment, maybe that makes a difference? – meir shapiro Jul 16 '15 at 12:26
  • @mDC The aList doesn't contain any nulls. I just can't map all instances of A to a B instance so the CreateB() method returns null in this case. – meir shapiro Jul 16 '15 at 12:27
  • @mDC What contents of bList do you get if you replace `CreateB` with `return null;`? – Pavel Krymets Jul 16 '15 at 12:30

1 Answers1

2

Both aList.Select(a => B.CreateB(a)).Where(b => b != null).ToList(); and aList.Select(B.CreateB).Where(b => b != null).ToList(); use the same overload of Select method.

I tested it with LinqPad and got the following output:

LinqPad

So Select doesn't filter anything. What version of Resharper and VisualStudio are you using?

Latest ReSharper on VS2013 doesn't tell anything:

Latest ReSharper on VS2013

Pavel Krymets
  • 6,253
  • 1
  • 22
  • 35
  • Thanks for testing. I'm using VisualStudio 2012 with Resharper 9.0 update 1. – meir shapiro Jul 16 '15 at 12:29
  • Turns out this is a bug in ReSharper. I debugged the Where clause by changing it to: .Where(item => { return item != null; }) and while Resharper says "Expression is always true" it is actually false. – meir shapiro Jul 16 '15 at 12:47
  • 1
    Try upgrading to ReSharper 9.1.1 or the 9.2 EAP. If it's still reported as an error, it's a bug, and should be reported to https://youtrack.jetbrains.com – citizenmatt Jul 16 '15 at 13:25