31

I'm writing an add-in for ReSharper 4. For this, I needed to reference several of ReSharper's assemblies. One of the assemblies (JetBrains.Platform.ReSharper.Util.dll) contains a System.Linq namespace, with a subset of extension methods already provided by System.Core.

When I edit the code, it creates an ambiguity between those extensions, so that I cannot use OrderBy, for instance. How could I solve this? I would like to use the core LINQ extensions, and not the ones from ReSharper.

I get the following error when trying to compile:

The call is ambiguous between the following methods or properties: 'System.Linq.Enumerable.OrderBy<string,int>(System.Collections.Generic.IEnumerable<string>, System.Func<string,int>)' and 'System.Linq.Enumerable.OrderBy<string,int>(System.Collections.Generic.IEnumerable<string>, System.Func<string,int>)'

EDIT: I tried the suggestion below, unfortunately without luck. In the meanwhile, I "solved" the problem by removing references to System.Core. This way I could use the extensions provided by ReSharper DLL files.

I uploaded a sample program where I just imported the ReSharper DLL files I needed. I changed the alias of System.Core to SystemCore, added the extern alias directive, but it still didn't work. If I missed something, please let me know. P.S. The references are to ReSharper v4.1 DLL files installed in the default directroy in "C:\Program Files\JetBrains\ReSharper\v4.1\...".

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Igal Tabachnik
  • 31,174
  • 15
  • 92
  • 157

10 Answers10

44

This is probably one of those rare cases where it makes sense to use an extern alias.

In the properties page for the reference to System.Core (i.e. under References, select System.Core, right-click and select "Properties"), change the "Aliases" value to "global,SystemCore" (or just "SystemCore" if it's blank to start with).

Then in your code, write:

extern alias SystemCore;
using SystemCore::System.Linq;

That will make all the relevant types etc in System.Core.dll's System.Linq namespace available. The name "SystemCore" here is arbitrary - you could call it "DotNet" or something else if that would make it clearer for you.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks a lot for the answer, however I still have an issue. I updated my original post. – Igal Tabachnik Jan 17 '09 at 15:57
  • It should work fine if you've got the alias specified in the reference. The error you're getting is what I see if I haven't set the "Aliases" property on the reference itself. – Jon Skeet Jan 17 '09 at 16:05
  • Thanks again Jon for your help, but unfortunately this still didn't solve the ambiguity issue. Do you have any other suggestions, perhaps? – Igal Tabachnik Jan 17 '09 at 17:14
  • So do you have exactly the original problem? If you've *only* got that using directive, you shouldn't have a problem. Could you post a short but complete program which demonstrates the problem (including extern alias)? – Jon Skeet Jan 17 '09 at 17:46
  • I uploaded a tiny program with the problem. I know you use ReSharper yourself, Jon, so you probably have the referenced DLLs. Again, thanks a lot! :) – Igal Tabachnik Jan 17 '09 at 19:22
  • 1
    By the way, this utterly fails in .Net 4.0 – Dmitri Nesteruk May 14 '10 at 15:38
  • I suspect there is a bug in the C# compiler that causes it to ignore the "extern alias" prefix. For example, "using SystemCore::System.Linq" actually imports extension methods from ALL System.Linq namespaces, not just the one in SystemCore. – Qwertie Apr 20 '11 at 19:15
  • Oh, I see my suspicion was confirmed in the answer below. Except the bug works differently than I thought. In my case, I added a reference to LinqBridge.dll and gave it the alias "linqbridge", but "using System.Linq" imported the extension methods from linqbridge despite the lack of a prefix in the "using" statement. – Qwertie Apr 20 '11 at 19:22
  • 1
    Also there's a bug using aliases in an assembly that also has a xaml file in it. https://connect.microsoft.com/VisualStudio/feedback/details/615953/reference-aliases-are-ignored-on-projects-containing-some-xaml-files – Cameron MacFarland Nov 07 '12 at 09:07
  • Tutorial for implementing this sollution: https://blogs.msdn.microsoft.com/ansonh/2006/09/27/extern-alias-walkthrough/ – ephraim Nov 22 '17 at 09:45
7

This isn't really an answer, but may provide an easier way for others to reproduce the issue (from the command-line - you could do it with two projects in Visual Studio if you want).

1) Create BadLinq.cs and build it as BadLinq.dll:

using System.Collections.Generic;

namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable<T> Where<T>(this IEnumerable<T> source, 
                                              Func<T,bool> predicate)
        {
            return null;
        }
    }
}

2) Create Test.cs:

extern alias SystemCore;

using System;
using SystemCore::System.Linq;

static class Test
{
    static void Main()
    {
        var names = new[] { "Larry", "Curly", "Moe" };

        var result = names.Where(x => x.Length > 1);
    }
}

3) Compile Test.cs specifying the extern alias:

csc Test.cs /r:BadLinq.dll /r:SystemCore=System.Core.dll

This fails with:

Test.cs(11,28): error CS1061: 'System.Array' does not contain a definition for 'Where' and no extension method 'Where' accepting a first argument of type 'System.Array' could be found (are you missing a using directive or an assembly reference?)

If you change it to not try to use an extension method (i.e. Enumerable.Where) it works fine with the extern alias.

I think this may be a compiler bug. I've emailed a private mailing list which the C# team reads - I'll update this answer or add a new one when I hear back.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Hey Jon. I was wondering, out of curiosity, have you got the answer back? – Igal Tabachnik Feb 09 '09 at 21:37
  • No, I haven't heard back on this one I'm afraid. – Jon Skeet Feb 09 '09 at 21:43
  • it has now been over two years since you posted this. Did you ever find out why this did not work? I'm stumbled upon this question accidentally, and am now very curious. – Kevin Cathcart Apr 06 '11 at 21:13
  • @Kevin: Nope, but I'm pleased to say I've just tested it with the C# 4 compiler, and it works :) – Jon Skeet Apr 06 '11 at 21:46
  • Someone reported this (sadly not fixed in C# 3/VS 2008): https://connect.microsoft.com/VisualStudio/feedback/details/510113/methods-disambiguated-with-extern-alias-cannot-be-invoked-as-extension-methods – Qwertie Apr 20 '11 at 19:19
2

This is no longer an issue, since I am able to use the LINQ extensions, as provided by ReSharper DLL files, even while targeting .NET 3.0.

Mr. Skeet was right again! I am able to use full LINQ syntax, while targeting .NET 3.0 in the project's properties and not referencing System.Core!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Igal Tabachnik
  • 31,174
  • 15
  • 92
  • 157
  • You should be able to use LINQ syntax as that just get translated by the compiler. What happens when you try to use a query expression? – Jon Skeet Jan 18 '09 at 08:14
  • Hey Jon. Seems that you're right again!, as always ;) I though this was a ReSharper issue, but it isn't! LINQ synax works, System.Core not referenced, DLL is targeted for C# 3.0 :) – Igal Tabachnik Jan 18 '09 at 08:25
  • Do you mean targeting .NET 3.0, by the way? You don't target a language version. – Jon Skeet Jan 18 '09 at 08:41
  • D'oh! I meant the target framework in project's properties. I haven't fully woke up, I suppose :) – Igal Tabachnik Jan 18 '09 at 08:59
  • 1
    @Igal - In your question you mentioned nothing helped, and I see you accepted your answer as solution. Can you explain please how you manged to really solve it, rather than removing system.core.dll? Thkx – ephraim Sep 13 '17 at 08:46
2

In order for ReSharper to be as compatible as possible with the variety of solutions it is used with, it is built against .NET 2.0. LINQ, etc. came in in C# 3.0, so they are not available in that version of the Framework. So, JetBrains added in their own version.

The solution is to build your addin against .NET 2.0 as well.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

I had the ambiguous reference problem using System.ComponentModel. Visual Studio was complaining that a DLL file exists in both v2 and v4. I was able to resolve it by removing the reference to the System DLL file and readding it.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ujain
  • 466
  • 5
  • 4
  • that did the trick for me. for future readers: in my case DynamicQueryable was in both EF extensions and Linq.Dynamic. – SHM Jan 29 '18 at 08:26
0

I had the same problem, even with extern alias, and I raised it as a compiler bug on Connect. The workaround for the time being is to forgo the extension method syntax.

The bug is fixed for Visual Studio 2010.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ben Challenor
  • 3,365
  • 1
  • 35
  • 35
0

I had a similar situation. After two hours struggling I realized I had duplicate namespace names in my libraries. If you are using file Dynamic.cs published by Microsoft, the only thing you need to do is rename the current namespace to something else, and it will be fixed.

//Copyright (C) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;

namespace System.Linq.Dynamic    <- for example to Linq.Dynamic
{
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ryan
  • 1
0

I found this same sort of ambiguity when use PagedList in MVC (.Net 4.5, MVC 5). I found that if I took the object for the argument that was ambiguous and cast it explicitly first, the problem was resolved. To if the ambiguity was between a method that takes System.Linq.Enumerable and one that takes System.Collections.Generic.IEnumerable as the parameter in question, and the source is of type System.Collections.Generic.IEnumerable, I don't use the extension method on it. I cast it.In this example, my repository method returns a List:

searchRequest.CaseSearchResults = csr.SelectMatchingCases(searchRequest);
var results = searchRequest.CaseSearchResults.AsEnumerable<CaseSearchResult>();
int pageNum = (int)(ViewBag.PageNum ?? 1);
var pageResults =results.ToPagedList<CaseSearchResult>(pageNum, 5);

Calling the extension method on searchRequest.CaseSearchResults caused the ambiguity error; explicitly casting to results and then calling the extension on that worked.

Joey Morgan
  • 823
  • 6
  • 9
0

It is really a compiler error.

I had the same problem, and I solved it just by cleaning and rebuilding the project. After that the problem disappeared.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • yes, it can be that, but I think a 9k rep user would figure that out. :) In more complex codes (>30k LOC) it can happen that the error really means something. – csomakk Dec 08 '12 at 03:05
0

One solution would be to move all your code out to a partial class that uses the ReSharper code. In there, you'd import only the ReSharper namespace and not System.Core.

In the rest of the partial class, you'd import all the other namespaces you need, including System.Core, but not the ReSharper namespace.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Fabrice
  • 3,094
  • 3
  • 28
  • 31
  • Thanks for the suggestion, however the ambiguity occurs on the assembly level, not specific class, therefore your suggestion doesn't solve it, unfortunately. – Igal Tabachnik Jan 18 '09 at 08:03