Question

I have the following BindingList derived class.

class MyBindingList<T> : BindingList<T> where T: class
{
  public T GetRecord(T obj)
   {
      return base.Where(t => t.Equals(obj)) //Where and Select not found on base :(
             .Select(t => t).FirstOrDefault();
   }
}

Compiler is giving me the following error

error CS0117: 'System.ComponentModel.BindingList' does not contain a definition for 'Where'

What am I missing ?

Was it helpful?

Solution

The problem is the way in which you're calling the extension method. You just need to use this instead of base. Calling extension methods on this is relatively unusual, but does need the this explicitly... and it can't be base, which suggests you're trying to call a method declared in one of the ancestors in the type hierarchy. A method invocation using base does not go through extension method invocation checks. From the C# 5 spec, section 7.6.5.2:

In a method invocation (§7.5.5.1) of one of the forms

expr . identifier ( )
expr . identifier ( args )
expr . identifier < typeargs > ( )
expr . identifier < typeargs > ( args )

if the normal processing of the invocation finds no applicable methods, an attempt is made to process the construct as an extension method invocation.

That's not the case in your code. (base isn't an expression in itself. Having said that, I believe section 7.6.8 of the C# spec is inconsistent with this. I'll raise that with the C# team.)

This compiles fine:

public T GetRecord(T obj)
{
    return this.Where(t => t.Equals(obj))
               .Select(t => t).FirstOrDefault();
}

(I added a return type to the method - please take more care when asking questions in future, given the number of mistakes it seems you had in this one.)

OTHER TIPS

Select accepts a Func<TSource, TResult>, but you're passing t, which is an undeclared symbol... it should be

Select(t => t)

Also, you should use this instead of base.

Anyway, the call to Select is useless, since you're not actually transforming the input. You can also merge the Where and FirstOrDefault into a single call.

   public T GetRecord(T obj)
   {
      return this.FirstOrDefault(t => t.Equals(obj));
   }

Try cast your instances from list

return base.Cast<T>().Where(t => t.Equals(obj)).Select(t).FirstOrDefault();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top