Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call is ambiguous error using Linq

First of all, sorry for excesive generic name classes. My employer is paranoid and I know for sure he roams this site. Ok, so I have this code:

var fooObj = new MyFooClass()
{
    fooField1 = MyEnum.Value3, 
    fooField2 = false,
    fooField3 = false,
    fooField4 = otherEntity.OneCollection.ElementAt(0) as MyBarClass
}

where otherEntity.OneCollection is an ISet. ISet is a NHibernate collection class that implements IEnumerable. If I try to compile this code I get this error:

Error 2     The call is ambiguous between the following methods or properties: 
'System.Linq.Enumerable.ElementAt<MyFirm.Blah.Blah.ClassyClass>    (System.Collections.Generic.IEnumerable<MyFirm.Blah.Blah.ClassyClass>, int)'
and 
'System.Linq.Enumerable.ElementAt<MyFirm.Blah.Blah.ClassyClass>(System.Collections.Generic.IEnumerable<MyFirm.Blah.Blah.ClassyClass>, int)'    

But if I remove the using System.Linq at the beginning of the class and change the code to this:

var fooObj = new MyFooClass()
{
    fooField1 = MyEnum.Value3, 
    fooField2 = false,
    fooField3 = false,
    fooField4 = System.Linq.Enumerable
                     .ElementAt(otherEntity.OneCollection, 0) as MyBarClass
}

it compiles and works. (? operator to check if OneCollection has elements removed for the sake of clarity)

Could anyone explain this error to me?

In case is relevant: I'm using Visual Studio 2008, targeting .NET Framework 3.5 and using ReSharper 5.1.

NOTE.- Edited to clarify which concrete IEnumerable is the collection, sorry for that.

like image 948
CMPerez Avatar asked Apr 08 '13 08:04

CMPerez


2 Answers

This is very strange.

The error claims that there's an ambiguity between two completely identical signatures.

The only thing I can think of is that you might somehow have the 'references' messed up in your project and that maybe you have i.e. reference both to 'System.Core 3.5' and 'System.Core 3.5.0.1' (contrived example).. You would get such error in this case, but yet, I cannot think why System.Linq.Enumerable.ElementAt(otherEntity.OneCollection works - it should report the same problem.

.. or maybe you somehow made your 'OneCollection' implement the IEnumerable twice in some wicked way? But then, I think the error message would be different.

like image 116
quetzalcoatl Avatar answered Oct 10 '22 17:10

quetzalcoatl


To remove the ambiguous reference, you have to be more explicit. There are two options.

First, you could make your IEnumerable generic, like:

IEnumerable<MyFooClass> = new List<MyFooClass>();
...
var fooObj = new MyFooClass()
{
     fooField1 = MyEnum.Value3, 
     fooField2 = false,
     fooField3 = false,
     fooField4 = otherEntity.OneCollection.ElementAt(0) as MyBarClass
 }

Or second; if it's a non-generic IEnumerable, do a cast:

IEnumerable = new List<MyFooClass>();
...
var fooObj = new MyFooClass()
{
     fooField1 = MyEnum.Value3, 
     fooField2 = false,
     fooField3 = false,
     fooField4 = otherEntity.OneCollection.Cast<MyFooClass>().ElementAt(0)
 }
like image 31
L-Four Avatar answered Oct 10 '22 19:10

L-Four