Permalink
Cannot retrieve contributors at this time
description | title | ms.date | f1_keywords | helpviewer_keywords | ms.assetid |
---|---|---|---|---|---|
Compiler Error CS0121 |
Compiler Error CS0121 |
08/14/2018 |
CS0121 |
CS0121 |
316cb77e-a500-4129-ae1b-e68b9188fd3e |
Compiler error CS0121
The call is ambiguous between the following methods or properties: ‘method1’ and ‘method2’
Due to implicit conversion, the compiler was not able to call one form of an overloaded method. You can resolve this error in one of the following ways:
- Specify the method parameters in such a way that implicit conversion does not take place.
- Remove all overloads for the method.
- Cast to proper type before calling the method.
- Use named arguments.
Example 1
The following examples generate compiler error CS0121:
public class Program { static void f(int i, double d) { } static void f(double d, int i) { } public static void Main() { f(1, 1); // CS0121 // Try the following code instead: // f(1, 1.0); // or // f(1.0, 1); // or // f(1, (double)1); // Cast and specify which method to call. // or // f(i: 1, 1); // or // f(d: 1, 1); // f(i: 1, d: 1); // This still gives CS0121 } }
Example 2
class Program2 { static int ol_invoked = 0; delegate int D1(int x); delegate T D1<T>(T x); delegate T D1<T, U>(U u); static void F(D1 d1) { ol_invoked = 1; } static void F<T>(D1<T> d1t) { ol_invoked = 2; } static void F<T, U>(D1<T, U> d1t) { ol_invoked = 3; } static int Test001() { F(delegate(int x) { return 1; }); // CS0121 if (ol_invoked == 1) return 0; else return 1; } static int Main() { return Test001(); } }
C# Compiler Error
CS0121 – The call is ambiguous between the following methods or properties: ‘method1’ and ‘method2′
Reason for the Error
You will receive this error when you usually call one of the overloaded method and the C# compiler is not able to call it because of the conflict with the parameters caused by implicit conversion.
For example, let’s have a look at the below C# code snippet.
namespace DeveloperPublishNamespace { public class DeveloperPublish { public static void Method1(int input1,double input2) { } public static void Method1(double input1,int input2) { } public static void Main() { Method1(5,5); } } }
This contains 2 overloaded functions with different parameter type. When this function is called with the parameter 5,5, it results with the below error.
Error CS0121 The call is ambiguous between the following methods or properties: ‘DeveloperPublish.Method1(int, double)’ and ‘DeveloperPublish.Method1(double, int)’ ConsoleApp1 C:UsersSenthilsourcereposConsoleApp1ConsoleApp1Program.cs 16 Active
C# compiler was not able to identify which overloaded method to call because of the values that is passed which results in the implicit conversion.
Solution
There are plenty of ways in which you can avoid this error. You can either specify the parameter type with the explicit conversion so that the implicit conversion doesn’t take place or possibly use a named arguments.
Содержание
- C# compiler: CS0121: The call is ambiguous between the following methods or properties
- 8 Answers 8
- The call is ambiguous between the following methods or properties (bug??)
- 4 Answers 4
- Update:
- C# generic method resolution fails with an ambiguous call error
- 2 Answers 2
- Error CS0121 with double and int
- 2 Answers 2
- C# compiler should report CS0121 consistently between VS2017 and VS2019, when ambiguous call is detected in named method syntax #35361
- Comments
C# compiler: CS0121: The call is ambiguous between the following methods or properties
This is the craziest what I’ve seen since a Fody plugin ruined my assembly by emitting invalid code and control flow varied random at runtime. No Fody this time.
- The whole story is within one project.
- The GetMessage extension method is there since weeks.
- The issue is started since 2 hours, and I can not figure out what it is.
- There is only one GetMessage extension method.
The error message (see the pic) lists two identical method specification
Error CS0121 The call is ambiguous between the following methods or properties: ‘ComiCalc.Data.ExceptionExtensions.GetMessage2(System.Exception)’ and ‘ComiCalc.Data.ExceptionExtensions.GetMessage2(System.Exception)’ ComiCalc.Data D:2014Develop.vsonlineComiCalcsrcComiCalc.DataServicesUserService.cs 61
If I change both the call, both the method definition (only 2 edits in 2 places) to GetMessage2, then I got exactly the same error message just referring to the GetMessage2.
and here is the single one method:
8 Answers 8
Make sure you don’t reference the output binary in your project references (i.e., the project references itself). This has happened to me in the past with Resharper (the addition of the output binary to the project references), so the extension method is both in the source and in the binary reference.
Delete bin folder > open project > build solution.
Got the same error because my project referenced to a dll, and at the same time had a transitive dependency to the same dll but at different file path.
Spotted it using extra logging during the build (Tools -> Options -> Build and Run ->output verbosity to Detailed or Diagnostic) by searching for dependency dll name: in Task «Csc» there were two occurrences of /reference with the dll
Fix was to point references to the same dll path
In my case, Resharper had created a new file named Annotations1.cs file. I just deleted it and the problem solved. Maybe you need delete debug / release / obj and clean / rebuild solution.
I created a new project and moved all files except ‘bin’, ‘references’, ‘obj’ and boom. It works like charm..
I had two exact classes created by a DB tool, because was executed 2 times with different parameters. I search by the class name and remove the newer, after that everything goes OK.
In my case I had the «publish» folder within my project folder. Removing the «publish» folder solved it for me.
In my case, I hit the same problem [impossible resolution conflicts between a single method and itself] because I used C# 8.0 and its shiny new features to build three projects that depend upon each other, transitively, like this:
- Project C depends on project B.
- Project B depends on project A.
- Project C calls APIs from types in project B that inherit types from project A. Some of those APIs have nullable reference type parameters.
Also, I had nullability checking enabled only for project A, and completely disabled for projects B and C.
The fix for me was to enable nullable annotations in project B (I did this without also enabling warnings).
I speculate that this fixes the problem by ensuring there weren’t two completely different compiler modes (nullable annotated on/off) reprocessing the same interface definition, while building two projects (A and B), and then up putting conflicting nullability annotations on their respective outputs.
Источник
The call is ambiguous between the following methods or properties (bug??)
Inside the new folder, create a class with an Extension Method. For example:
Choose a View and try to use this new Extension Method
You will get this Exception:
Anyone here has more information about it? Is it wrong to create an App_code in an ASP.NET MVC(?) Web Applications?
4 Answers 4
MVC projects created in Visual Studio use Web application project model by default. App_Code is mostly used by Web site model. I suggest reading about differences between them (another question covers this and it’s also covered extensively on MSDN). If you add a source file to App_Code in a Web application project, Visual Studio will compile it to a DLL (since it’s included in the project) and puts it in /bin . At run time, the ASP.NET compiler sees App_Code and tries to compile the source in a different assembly. As a consequence, two separate classes with identical names will exist in two different assemblies and when the ASP.NET parser tries to compile the .aspx file, it’ll fail to choose one.
Update:
Are those two (extension method and the class you’re instantiating) in a single .cs file? Otherwise, probably, the class you’re instantiating is in a source file with Build Action (right click on file, click properties) set to Content which tells Visual Studio to skip it in the build process (in that case, you won’t be able to reference it in other .cs files that are outside App_Code but you’ll be able to use it in the view since it’ll only come to life at run time.) If the build action is Compile, you’ll get an error. The issue is definitely not specific to extension methods. Visual Studio seems to be smart enough to set it to Content by default for source files added to App_Code .
Источник
C# generic method resolution fails with an ambiguous call error
Suppose I have defined two unrelated types and two extension methods with the same signature but different type filters:
Then when I write new Foo().Frob(); I get an error
error CS0121: The call is ambiguous between the following methods or properties: ‘FooExtensions.Frob (TFoo)’ and ‘BarExtensions.Frob (TBar)’
Could someone explain why this fails and how to avoid it?
EDIT: This happens in VS2015 Update 3 and VS2017 RC.
EDIT2: The idea here is to have fluent API that works on a class hierarchy:
2 Answers 2
The constraint of a generic type parameter is not part of the method’s signature. These two methods are essentially the same from a resolution point of view; when the compiler tries to resolve the call it sees two valid methods and it has no way to choose the better one, therefore the call is flagged as ambiguous.
You can read more about this issue here.
Actually, the general goal (from your description and my practice and view) is more concise representation for sets of “similar” extension for classes. The “similarity” partially may be that names of these classes are quite long multipart camel-case identifiers which even do not always differ in the first part.
So, using generics is good only in case of class inheritance. For non-inheritable classes solution is using short class aliases.
Источник
Error CS0121 with double and int
I have an error:
Error CS0121 The call is ambiguous between the following methods or properties: ‘Program.calculateFee(double, int)’ and ‘Program.calculateFee(double)’ DailyRate.
here is my code:
edit: why does this one do work??
2 Answers 2
EDIT
The second example works because you have fixed the misspelling of calulateFee() , allowing the compiler to bind to the method that exactly matches the call (no parameters).
When calculateFee was misspelled, the compiler did not find a method that exactly matched the name and parameters, so it began searching for appropriate overloads. It find two — one with one optional parameter and one with two. The overload resolution rules do not allow the compiler to pick one method over the other, so it results in a build error.
- If more than one candidate is found, overload resolution rules for preferred conversions are applied to the arguments that are explicitly specified. Omitted arguments for optional parameters are ignored.
- If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.
Since the last method exactly matches your calling signature, it is chosen. When it was misspelled, two other «equally good» candidates were found. Since optional parameters are ignored, there are no rules to dictate that one overload be chosen over another.
ORIGINAL ANSWER
You have one method with an optional double parameter and another method with an optional double parameter and an optional int parameter. When you call it with no parameters the compiler doesn’t know if you want to call the method with no parameters, with just the double parameter or with the double and int parameters. You have some options to fix this:
Either use optional parameters or use overloads; there’s no reason to use both.
Источник
C# compiler should report CS0121 consistently between VS2017 and VS2019, when ambiguous call is detected in named method syntax #35361
Version Used: VS2017 Enterprise (15.9.11) and VS2019 Enterprise (16.0.2)
Steps to Reproduce:
- Create a .NET Standard 2.0 class library
- Reference NuGet package System.Threading.Task.Dataflow v4.9.0
- Replace Class1.cs contents with
- Compile in VS2017 Enterprise
- Compile in VS2019 Enterprise
- VS2017 will have thrown a CS0121 compilation exception, whereas VS2019 won’t have
- Changing from the Named method syntax to either the lambda or cast suggestions used in the «FIX» comments above, does resolve the error in VS2017
Expected Behavior: Both VS2017 and VS2019 either report (or handle) the «ambiguous» declaration the same, when using Named method syntax
Actual Behavior: VS2019 Enterprise (and hosted 2019 build agent in Azure DevOps) compiles successfully, but VS2019 Enterprise (and hosted 2017 build agent in Azure DevOps) throws a compilation error of CS0121 The call is ambiguous between the following methods or properties: ‘TransformBlock .TransformBlock(Func )’ and ‘TransformBlock .TransformBlock(Func >)’
This is likely shoddy architecture, but regardless of that, VS2017 and VS2019 compilers should really behave consistently, between the 2 versions.
I’ve tried the following Dataflow versions, which all exhibit the same behaviour:
- 4.7.0
- 4.9.0
- 4.10.0-preview4.19212.13
The text was updated successfully, but these errors were encountered:
Источник
- Remove From My Forums
-
Question
-
Greetings!
I’m working with LINQ and I «copied» a class from a blog that would convert the IEnumerable information from a LINQ query to a DataTable, and I’m getting an error that I just cannot get.
After looking for answers, I read an article that suggests this bug is because of VS 2008 as it does not happen in VS 2005.
I would like to know the opinion of the members of this forum and see if there is a workaround.
The following is the Error, and after that I will post my code. Thank you so much!
CS0121: The call is ambiguous between the following methods or properties: ‘CustomerPriceAgreement.ConvertDataTable.ToADOTable<AnonymousType#1>(System.Collections.Generic.IEnumerable<AnonymousType#1>, CustomerPriceAgreement.ConvertDataTable.CreateRowDelegate<AnonymousType#1>)’ and ‘CustomerPriceAgreement.ConvertDataTable.ToADOTable<AnonymousType#1>(System.Collections.Generic.IEnumerable<AnonymousType#1>, CustomerPriceAgreement.ConvertDataTable.CreateRowDelegate<AnonymousType#1>)’
CODE
public static DataSet BindCustomerGrid(DataSet ds, bool expired) { DataTable dtCutomers = new DataTable(); dtCutomers = CreateDataTableCustomers(dtCutomers); PriceCustomerAgreementDataContext PCA = new PriceCustomerAgreementDataContext(); PriceCustomerAgreement_Customer customer = new PriceCustomerAgreement_Customer(); var query = from customers in PCA.PriceCustomerAgreement_Customers select new { customers }; if (expired) { //d = date query = query.Where(d => d.customers.ExpDate < DateTime.Today); } var PriceCustomerAgreement = from rows in query select new { rows.customers.ID, rows.customers.Customer, rows.customers.PartNumber, rows.customers.Price, rows.customers.Qty, EntryDate = rows.customers.EntryDate.Value.ToShortDateString(), rows.customers.SystemUser, rows.customers.Notes, ExpDate = rows.customers.ExpDate.Value.ToShortDateString() }; DataTable dt = PriceCustomerAgreement.ToADOTable(rec => new object[] { PriceCustomerAgreement }); } namespace CustomerPriceAgreement { public static class ConvertDataTable { public static DataTable ToADOTable<T>(this IEnumerable<T> varlist, CreateRowDelegate<T> fn) { DataTable dtReturn = new DataTable(); // Could add a check to verify that there is an element 0 T TopRec = varlist.ElementAt(0); // Use reflection to get property names, to create table // column names PropertyInfo[] oProps = ((Type)TopRec.GetType()).GetProperties(); foreach (PropertyInfo pi in oProps) { Type colType = pi.PropertyType; if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>))) { colType = colType.GetGenericArguments()[0]; } dtReturn.Columns.Add(new DataColumn(pi.Name, colType)); } foreach (T rec in varlist) { DataRow dr = dtReturn.NewRow(); foreach (PropertyInfo pi in oProps) { dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue(rec, null); } dtReturn.Rows.Add(dr); } return (dtReturn); } public delegate object[] CreateRowDelegate<T>(T t); } }
Eduardo
Answers
-
-
Marked as answer by
Friday, November 13, 2009 4:20 AM
-
Marked as answer by
slinger 4 / 4 / 0 Регистрация: 21.04.2012 Сообщений: 132 |
||||
1 |
||||
01.09.2017, 12:32. Показов 5316. Ответов 6 Метки нет (Все метки)
Всем добрый день, Работаю с библиотекой https://github.com/Thraka/SadC… -a-Console Первое место откуда вылезает ошибка:
__________________
0 |
Администратор 15248 / 12287 / 4904 Регистрация: 17.03.2014 Сообщений: 24,883 Записей в блоге: 1 |
|
01.09.2017, 14:05 |
2 |
slinger, думаю будет проще помочь если ты выложишь весь проект
0 |
4 / 4 / 0 Регистрация: 21.04.2012 Сообщений: 132 |
|
01.09.2017, 15:22 [ТС] |
3 |
Глупый вопрос, но никогда с ним не сталкивался: как выгрузить весь прокт из Visual Studio, если он состоит из разнх проектов? Один создавался по шаблону и 2 подключенных?
0 |
4 / 4 / 0 Регистрация: 21.04.2012 Сообщений: 132 |
|
02.09.2017, 00:56 [ТС] |
5 |
Прикладываю файл.
0 |
Администратор 15248 / 12287 / 4904 Регистрация: 17.03.2014 Сообщений: 24,883 Записей в блоге: 1 |
|
02.09.2017, 08:00 |
6 |
slinger, ошибки компиляции возникают потому что ты включил в решение исходный код SadConsole с github и добавил ссылку на него же через NuGet. Это привело к дублированию кода. Отсюда и ошибка «The call is ambiguous between the following methods» с указанием одноименных методов. Так делать не надо. Вместо этого нужно создать новый проект, установить в нем NuGet пакет SadConsole и далее писать код.
0 |
4 / 4 / 0 Регистрация: 21.04.2012 Сообщений: 132 |
|
02.09.2017, 09:31 [ТС] |
7 |
OwenGlendower, спасибо за ответ!
0 |
#c# #implicit-conversion #ambiguous-call
Вопрос:
У меня есть несколько классов C#, MyChar, Myint, myDouble, которые переносят символы char, int и double. У каждого есть неявный оператор преобразования из обернутого типа в определенный пользователем. У меня также есть набор перегруженных функций, toString(MyChar), toString(myInt), toString(myDouble).
Я хочу вызвать toString(MyChar), передав буквальное значение символа, например «A». Но компиляция завершается неудачно с CS0121, «Вызов неоднозначен между следующими методами или свойствами:» toString(MyChar)» и «toString(myInt)»». И у меня возникает аналогичная проблема, если я передаю значение int.
public class MyChar
{
private MyChar(char val) => Value = val;
public static implicit operator MyChar(char val) => new MyChar(val);
public char Value { get; }
}
public class MyInt
{
private MyInt(int val) => Value = val;
public static implicit operator MyInt(int val) => new MyInt(val);
public int Value { get; }
}
public class MyDouble
{
private MyDouble(double val) => Value = val;
public static implicit operator MyDouble(double val) => new MyDouble(val);
public double Value { get; }
}
public class ConversionTests
{
public void DoIt()
{
Console.WriteLine(ToString('A')); // CS0121
Console.WriteLine(ToString(1)); // CS0121
}
private static string ToString(MyChar c) => $"{c.Value}";
private static string ToString(MyInt i) => $"{i.Value}";
private static string ToString(MyDouble d) => $"{d.Value}";
}
Я обнаружил, что могу заставить компилятор правильно принимать значение int, добавив неявное преобразование из myInt в myDouble
public class MyDouble
{
private MyDouble(double val) => Value = val;
public static implicit operator MyDouble(double val) => new MyDouble(val);
public static implicit operator MyDouble(MyInt val) => new MyDouble(val.Value);
public double Value { get; }
}
...
public void DoIt()
{
Console.WriteLine(ToString('A')); // CS0121
Console.WriteLine(ToString(1)); // now compiles :-)
}
Я предполагаю, что это работает, потому что механизм разрешения теперь считает, что преобразование в myDouble теперь выполняется по маршруту 1 -> myInt ->> myDouble, и это не может произойти неявно, поскольку для этого требуется два пользовательских преобразования. В том же духе я могу ToString('A')
решить проблему правильно, добавив еще два неявных преобразования: MyChar в myDouble и MyChar в myInt.
Это нормально, так как оно отражает неявные преобразования, которые происходят между символами char, int и double. Но может ли кто-нибудь объяснить мне, почему исходный код, опубликованный выше, не будет компилироваться без дополнительных преобразований так, как мог бы понять простой мозг, подобный моему?
Комментарии:
1.A
Char
может быть неявно приведено к anInt
. Anint
может быть неявно приведено кdouble
. Учитывая неявные приведения кMy
типам, это означает, чтоToString('A')
это может быть обработано обоимиToString
методами. Вы можете удалить всеToString()
методы, кромеToString(MyInt)
, и код все равно будет работать2. Что ты пытаешься сделать? Вы пробуете что-то или это упрощенный случай реальной проблемы?
3. @PanagiotisKanavos Это самое простое сокращение проблемы, которую я нашел в своем коде. Я хочу представить полный API, поэтому у меня нет роскоши удалять методы. Я хочу использовать перегруженное имя, так как в сознании пользователя операция-это одно и то же, независимо от типа, на котором она выполняется. Чего я не понимаю, так это почему символ преобразования -> MyChar не выбран в качестве однозначного преобразования, поскольку он ближе, чем символ ->> int ->>> myInt.
4. опишите реальную проблему в самом вопросе. Ни одно из преобразований не находится ближе, чем другое. Все они требуют неявных приведений, поэтому ни одно из них не ближе другого. Для этих примеров существует несколько методов, которые могут быть вызваны после неявных приведений.
5.
as in the user's mind the operation is the same thing, irrespective of the type its operating on.
почему бы тогда не использовать общий метод? Приведите пример реальной проблемы. Вы можете использовать общий интерфейс для всех типов, использовать общие методы или использовать какой-либо другой трюк
Ответ №1:
A char
может быть неявно приведено к an int
. An int
может быть неявно приведено к double
. Учитывая неявные приведения к My
типам, это означает, что ToString('A')
это может быть обработано обоими ToString
методами.
Вы можете удалить все ToString()
методы, кроме ToString(MyInt)
, и код все равно будет работать:
public class ConversionTests
{
public void DoIt()
{
Console.WriteLine(ToString('A'));
Console.WriteLine(ToString(1));
}
private static string ToString(MyInt i) => $"{i.Value}";
}
Это напечатало бы :
65
1