86

I am making the following call to an extension method:

database.ExecuteScalar(command).NoNull<string>(string.Empty);

I get an error that the extension method is ambiguous .

I have two dlls with the same code that implement NoNull(string str) under different namespaces.

How can I explicitly refer to one namespace?

How would I have it done if it was the same namespace?

Update: I cannot rewrite the 3rd party dlls.

Elad Benda
  • 35,076
  • 87
  • 265
  • 471
  • I think using the full naming convention of the class you want to use (my.Lib1.class or my.Lib2.class) will solve your first quesntion. If you have the same asm name/version/culture/etc you will have to create multiple AppDomains since those cannot be loaded into the same domain. – Marvin Smit Dec 12 '11 at 13:17
  • @Marvin Smit: With extension methods you can't limit methods to one namespace through explicit namespaces like you can with classes. – Joel Etherton Dec 12 '11 at 13:19
  • `NoNull` is a pretty strange function too. Did you want to use the null coalescence operator `??`? – CodesInChaos Dec 12 '11 at 13:20
  • Why do you have 2 functions containing the same code? – demoncodemonkey Dec 12 '11 at 13:21

5 Answers5

109
  1. Remove the ambiguity by redefining or eliminating one of the methods at the source. You don't need redundancy.
  2. If you do not control the source, include only one of them in your class file via the using directive.
  3. If you still need both namespaces in the given class file, invoke the version you wish simply as a static class call, unambiguously identifying the method via the (potentially fully qualified) class name.
 Abc.Xyz.ExtensionsClass.NoNull(database.ExecuteScalar(), string.Empty);
 // <Abc.Xyz.> is only necessary if the classes themselves match names
 // if not, only <ClassName>.<MethodName> is needed
Anthony Pegram
  • 123,721
  • 27
  • 225
  • 246
63

Just in case somebody will need this...

Ambiguity can be resolved if concurrent namespaces which have extension methods with same name, are included at different levels (most inner included namespace will have priority).

For example:

using Namespace1;
namespace MyApplication 
{
    using Namespace2;
    ...
    db.Execute(); // Namespace2 Execute() will be called
}
pakeha_by
  • 2,081
  • 1
  • 15
  • 7
  • 6
    Very nice. Seems like a good enough solution for 99% of cases, the 1% would be where you need to resolve the ambiguity in two different ways for two method pairs ( or more) in the same class, since all I need is to workaround morelinq predicting the feature development of Linq (ToHashSet being added). it works great . – user1852503 Jul 09 '18 at 07:49
  • It took me a while to figure out why this wasn't working for me. Then I realized the second using statement should be inside the namespace brackets, but _not_ inside the method brackets. Now it works great! Thanks! – inejwstine Aug 24 '22 at 17:28
  • Agreed nice workaround. Interesting I got here due to MoreLinq too... – Ian Dec 20 '22 at 14:54
10

I would strongly suggest that you rename one of the extension methods. Depending on what else you do, you could possibly just remove the using directive for one of those namespaces, but that won't help if you need both namespaces for other things. (This leads to a suggestion to put extension methods in their own namespace, of course.) Renaming is likely to simplify things in general though.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Presumably it is the same function with the same code, renaming or changing the signature will more likely add confusion rather than simplify. – demoncodemonkey Dec 12 '11 at 13:20
  • 3
    @demoncodemonkey: Oh, I was assuming it actually did subtly different things. If it's the same code, then clearly it should be in a single assembly (and namespace). – Jon Skeet Dec 12 '11 at 13:26
  • 2
    @demoncodemonkey: If it's the same function, same code, different namespaces it's a code smell in a big way. – Joel Etherton Dec 12 '11 at 13:26
  • I am enjoying this problem now with MoreLinq and the new DistinctBy in System.lInq.Enumerable. – Victorio Berra Jan 25 '23 at 03:13
  • "This leads to a suggestion to put extension methods in their own namespace, of course." - interesting, that this was not considered with the `CollectionExtensions` in .NET Core! When porting an application from .NET Framework, you get either ambiguities or even crashes (e.g. as I have a null check for the key in my version of `GetValueOrDefault`) – LionAM Aug 22 '23 at 13:03
1

In my case the problem was, that both extension methods had the same namespace like Some.Namespace.Extensions, that i didn't have control over and thus couldn't change.

They were each located in a separate class, though. So I solved it by writing using static Some.Namespace.Extensions.HostExtensions instead of using Some.Namespace.Extensions as using a using statement with a static class is not possible.

Musti
  • 139
  • 1
  • 9
0

You should change the signature of one (or both of them) to differentiate what it does. This seems like duplication of code somewhere unless these do different things. Though if they do different things I would think you would differentiate that in the names. I'd recommend creating some sort of enumeration (a flag maybe) to pass as an extra argument to one of the methods.

Joel Etherton
  • 37,325
  • 10
  • 89
  • 104