Lets say I have 2 extension methods to string, in 2 different namespaces:
namespace test1
{
public static class MyExtensions
{
public static int TestMethod(this String str)
{
return 1;
}
}
}
namespace test2
{
public static class MyExtensions2
{
public static int TestMethod(this String str)
{
return 2;
}
}
}
These methods are just for example, they don't really do anything.
Now lets consider this piece of code:
using System;
using test1;
using test2;
namespace blah {
public static class Blah {
public Blah() {
string a = "test";
int i = a.TestMethod(); //Which one is chosen ?
}
}
}
The Question:
I know that only one of the extension methods will be chosen.
Which one will it be ? and why ?
Edit:
This also bothers me, but not as much because it's a static method in a static class after all:
How can I choose a certain method from a certain namespace ?
Usually I'd use Namespace.ClassNAME.Method()
... But that just beats the whole idea of extension methods. And I don't think you can use Variable.Namespace.Method()
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are static methods, but they're called as if they were instance methods on the extended type.
Extension methods enable developers to add custom functionality to data types that are already defined without creating a new derived type. Extension methods make it possible to write a method that can be called as if it were an instance method of the existing type.
The main advantage of the extension method is to add new methods in the existing class without using inheritance. You can add new methods in the existing class without modifying the source code of the existing class. It can also work with sealed class.
For an application programmer, extension methods are an incredibly powerful and expressive tool. They enable convenience, extensibility, and an improved intellisence experience. However, many of the features that make extension methods so useful for library consumers can be problematic for class library authors.
No method will be chosen: the call is ambiguous and will not compile.
Why can't you do Namespace.ClassNAME.Method()
? Certainly there is nothing that prevents you from treating extension methods as normal static methods, and in fact this is the only way for you to fix the ambiguity and have the program compile.
I had this exact question so I found this post two years later. However, I think it is important to note that this will only not compile and give the "The call is ambiguous" error if the code calling the duplicate extension methods is not in the same namespace as one of them.
If the OP were to change the namespace of his class Blah to either test1
or test2
, then the code compiles, and the extension in the same namespace as the caller is used - even when both namespaces are represented in the usings
. So if Blah is in the test1
namespace, "1" is returned, and if Blah is in the test2
namespace, "2" is returned.
I think this is important to add to the above answers, because I think one mainstream use-case is to have extensions in a local class library that references external extension libraries (e.g. devs share a common utility library, but have some local custom extensions that might unwittingly have the same name). By maintaining the custom local extensions in the same namespace as the code that uses them, you can maintain the extension call syntax and not have to revert to treating them as static method calls.
As Jon says, if both of these exist when you do the compilation, the compilation will just fail.
But if only one exists at the time of compilation and a external library later gets updated to add the second, the code you compiled will still continue to use the first one. This is because the compiler interally turns your code into the longhand form of calling namespace.classname.method.
I migrated big solution from .Net 4.7.1 to .Net 4.7.2. We use LINQ in our code, and we use well known and established library with name MoreLinq https://www.nuget.org/packages/morelinq/.
.Net 4.7.1 does not have .ToHashSet()
methods. We used .ToHashSet()
from MoreLinq library. And in the same class in the same cs-file we have both using System.Linq;
and using MoreLinq;
.
I retargeted a project to .Net 4.7.2 and the compiler showed The call is ambiguous
error as described above. The reason was that .Net 4.7.2 added new extension methods with the same name .ToHashSet()
.
I cannot reimplement huge code base. I cannot replace MoreLinq with another library. This is what I did. I created a new class in a new file where I have using System.Linq;
but not using MoreLinq;
. This is the file (ToHashsetHelpers.cs):
using System.Collections.Generic;
using System.Linq;
namespace Common.Helpers
{
/// <summary>
/// This class with only one method helps to resolve
/// name conflict between .Net 4.7.2 and MoreLinq libraries.
///
/// .Net 4.7.2 introduced a new extension method named '.ToHashSet()'.
/// But MoreLinq already has the same method.
///
/// After migrating our solution from .Net 4.7.1 to 4.7.2
/// C# compiler shows "The call is ambiguous" error.
///
/// We cannot have both "using System.Linq;" and "using MoreLinq;" in the same C# file that
/// uses '.ToHashSet()'.
///
/// The solution is to have method with different name in a file like this.
/// </summary>
public static class ToHashsetHelpers
{
/// <summary>
/// The name of this method is ToHashset (not ToHashSet)
/// </summary>
public static HashSet<TSource> ToHashset<TSource>(this IEnumerable<TSource> source)
{
// Calling System.Linq.Enumerable.ToHashSet()
return source.ToHashSet();
}
}
}
And I renamed all .ToHashSet()
to .ToHashset()
in entire solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With