Misunderstanding of .NET on overloaded methods with different parameters (Call Ambiguous)

Mohammad Nikravesh

I have a problem with some overloaded methods and I will try to give a simple implementation of it.

So here is a class contains two methods below:

public class MyRepo<TEntity>
{
    public List<TEntity> GetData(Expression<Func<TEntity, Boolean>> expression)
    {
        //Do something
    }

    public List<TEntity> GetData(Func<TEntity,Boolean> whereClause)
    {
        //Do something
    }
}

and this my entity:

public class MyEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Here is where I'm utilizing it:

{
    ...
    MyRepo<MyEntity> myRepo = new MyRepo<MyEntity>();
    myRepo.GetData(x => x.Id == 1); // The ambiguity point
    ...
}

The problem is that I just have two methods with same name and different arguments so, based on OOP polymorphism concepts, I expect .NET to understand my desired method.

But it's obvious .NET cannot understand it because the instance form of Expression<Func<TEntity, Boolean>> and Func<TEntity, Boolean> are the same and this the compile-time error which .NET raises:

The call is ambiguous between the following methods or properties:
    'Program.MyRepo<TEntity>.GetData(Expression<Func<TEntity, bool>>)' and
    'Program.MyRepo<TEntity>.GetData(Func<TEntity, bool>)'

The question is: how can I prevent this compile-time error?

My preference is to do not touch the way I'm calling GetData() at this line:

myRepo.GetData(x => x.Id == 1);
Alexei Levenkov

Lambda expressions (x=> x.Id==1) do not have type by themselves - they automatically "cast" to Expression or Func/delegate of matching type when type is known. I.e. Why must a lambda expression be cast when supplied as a plain Delegate parameter deals with similar issue just between different delegate types.

In your case methods that are potential candidate suggest both variants and compiler can't make a choice.

If you really have to keep same name then callers will have to specify type themselves:

 myRepo.GetData((Expression<Func<TEntity, Boolean>>)(x => x.Id == 1));
 myRepo.GetData((Func<TEntity, Boolean>)(x => x.Id == 2));

I don't think you can use extension method for one of alternatives as search will stop at the class level. So really having methods with different names is the only real option (if you need both). Consider if just Expression version is enough. Alternatively you can split them between different classes (similar how extensions of IQueryable take Expression when similar methods on IEnumerable take Func (see QueryableExtenasions).

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Ambiguous overloaded java methods with generics and varargs

Call Overloaded methods with ternary operator?

C++ call of overloaded constructor is ambiguous

Deleting overloaded function. C++11. Call of overloaded ... is ambiguous

Call of overloaded function is ambiguous although different namespace

Call of overloaded static_cast is ambiguous

Why "ambiguous reference to overloaded definition" for methods with different signatures?

How to call methods with different parameters as Action?

error: call of overloaded distance is ambiguous

error: call of overloaded 'abs(double)' is ambiguous

ambiguous call to overloaded function find_first_not_of

Why is this call to the overloaded function ambiguous?

How to resolve "fpclassify': ambiguous call to overloaded function

The call is ambiguous error for generics methods

Ambiguous call of overloaded class method

Ambiguous call to overloaded function in variadic template function

Can't call statically imported overloaded function when one with different parameters is defined locally?

Ambiguous call to overloaded function in Base class

Delphi Ambiguous Overloaded Call to MkDir

c++ templates and ambiguous call to overloaded function

Call of Overloaded Functions is Ambiguous

IntelliJ shortcut to auto complete parameters for overloaded methods?

call of overloaded ‘abs(double&)’ is ambiguous

"Call of overloaded function is ambiguous" even with different argument order

error: call of overloaded function ambiguous

Overloaded methods with optional parameters

C++ Call of overloaded function is ambiguous

Ambiguous call when overloaded methods take reverse iterators in arguments

Type deduction resullts in ambiguous call of overloaded function