#c# #.net #compiler-construction #operators #operator-overloading
#c# #.net #компилятор-конструкция #операторы #оператор-перегрузка
Вопрос:
У меня есть 2 класса с перегруженными операторами в пространстве имен с именем Dinero, это 2 класса:
Первый:
namespace Dinero
{
class Dollar
{
#region Atributos
public Double cant;
#endregion
#region Constructores
public Dollar()
{
this.cant = 0;
}
public Dollar(Double amount)
{
this.cant = amount;
}
#endregion
#region Sobrecarga de Operadores
public static Dollar operator (Euro eu, Dollar dol)
{
Dollar devolucion = new Dollar();
devolucion.cant = eu.cant (dol.cant * 1.3642);
return devolucion;
}
public static Dollar operator -(Euro eu, Dollar dol)
{
Dollar devolucion = new Dollar();
devolucion.cant = eu.cant (dol.cant * 1.3642);
return devolucion;
}
public static bool operator ==(Euro eu, Dollar dol)
{
if (eu.cant == (dol.cant * 1.3642))
return true;
else
return false;
}
public static bool operator !=(Euro eu, Dollar dol)
{
if (eu.cant != (dol.cant * 1.3642))
return true;
else
return false;
}
#endregion
}
}
Второй:
namespace Dinero
{
class Euro
{
#region Atributos
public Double cant;
#endregion
#region Constructores
public Euro()
{
this.cant = 0;
}
public Euro(Double amount)
{
this.cant = amount;
}
#endregion
#region Sobrecarga de operadores
public static Euro operator (Euro eu, Dollar dol)
{
Euro devolucion = new Euro();
devolucion.cant = eu.cant (dol.cant * 1.3642);
return devolucion;
}
public static Euro operator -(Euro eu, Dollar dol)
{
Euro devolucion = new Euro();
devolucion.cant = eu.cant - (dol.cant * 1.3642);
return devolucion;
}
public static bool operator ==(Euro eu, Dollar dol)
{
if (eu.cant == (dol.cant * 1.3642))
return true;
else
return false;
}
public static bool operator !=(Euro eu, Dollar dol)
{
if (eu.cant != (dol.cant * 1.3642))
return true;
else
return false;
}
#endregion
}
}
И когда я перехожу к основной программе (я не знаю, как вы, ребята, вызываете основной файл, я хотел бы знать, поскольку я всего лишь n00b), и я набираю это:
namespace Ejercicio_21
{
class Ejercicio_21
{
static void Main(string[] args)
{
Console.Title = "Ejercicio Nro 21";
Euro euro00 = new Euro(1);
Dollar dollar00 = new Dollar(1);
Euro sumaEuros = euro00 dollar00;
О последней строке компилятор говорит:
Ошибка 11 Вызов неоднозначен между следующими методами или свойствами: ‘Dinero.Euro.operator (Dinero.Euro, Dinero.Доллар)’ и ‘Dinero.Dollar.operator (Dinero.Euro, Dinero.Доллар) ‘
Я предполагаю, что это как-то связано с разными пространствами имен, но я не мог понять это, даже используя Google.
Это первый вопрос, который я задаю здесь, поэтому, пожалуйста, не доводите меня до забвения и, пожалуйста, извините за мой ужасный английский.
Примечание: я вынужден хранить классы Dollar и Euro в пространстве имен, отличном от основной программы.
Заранее благодарю вас.
Комментарии:
1. Не связано: пользователь не
Double
должен указывать сумму в валюте.double
иfloat
, с другой стороны, они больше подходят для научных вычислений (где «довольно близко» достаточно хорошо.)decimal
, С другой стороны, гарантирует, что ваши финансовые вычисления поддерживают необходимую вам десятичную точность.2. Вы также можете получить эту ошибку, если хотите начать с какого-то уже существующего кода (уйти во что-то) и не дать скопированному классу новое имя.
Ответ №1:
Нет, это не имеет никакого отношения к разным пространствам имен — просто у вас одна и та же сигнатура оператора, объявленная в двух местах:
public static Dollar operator (Euro eu, Dollar dol)
public static Euro operator (Euro eu, Dollar dol)
Компилятор не знает, какой из них вы хотите вызвать.
Честно говоря, я не думаю, что добавление значения в долларах к значению в евро имеет большой смысл для начала, но даже помимо этого, выполнение одной и той же операции «добавление долларов к евро» должно иметь один логический тип результата.
Если вы действительно хотите, чтобы две операции были действительными, я бы предложил вызвать методы экземпляра Plus
:
// In Dollar
public Dollar Plus(Euro eu)
// In Euro
public Dollar Plus(Dollar dol)
Затем:
Euro euro00 = new Euro(1);
Dollar dollar00 = new Dollar(1);
Euro sumaEuros = euro00.Plus(dollar00);
Почти так же ясно, но без двусмысленности.
Другая альтернатива, которую я не рекомендую, — сделать (скажем), чтобы тип первого операнда имел приоритет:
public static Dollar operator (Dollar dol, Euro eu)
public static Euro operator (Euro eu, Dollar dol)
Тогда вы могли бы сделать:
Dollar dol1 = ...;
Euro eu1 = ...;
Dollar dol2 = dol1 eu1;
Euro eu2 = eu1 do1;
Хотя это довольно ужасно.
Комментарии:
1. Прежде всего, спасибо. Должен ли я выбирать один из двух классов для размещения перегрузок операторов?
2. @Cristian: вы можете поместить операторы в оба класса, но нет смысла иметь два оператора с одинаковой сигнатурой .
3. Спасибо, но мой учитель заставляет нас перегружать операторы таким образом. Ваш метод явно лучше, но мне придется придерживаться перегрузки операторов.
4. @Cristian: Тогда вам нужно будет присвоить им разные подписи. Все еще плохая идея даже иметь операции добавления для этих типов, IMO…
5. Неплохо… Я попробую этот ужасный метод … моему учителю понравится что-то подобное, хахаха
Ответ №2:
Это связано с тем, что вы объявили
public static Your_Type operator (Euro eu, Dollar dol)
в обоих классах.
Поэтому ваш компилятор не знает, какой из них использовать…
Комментарии:
1. Прежде всего, спасибо. Должен ли я выбирать один из двух классов для размещения перегрузок операторов?
2. @Cristian: Джон Скит уже дал вам лучший ответ (как обычно) 🙂
Ответ №3:
Решена эта проблема в VS 2015 путем удаления дублированного кода, который был как в проекте, так и в пакете NuGet. При выгрузке проекта, в котором был дублированный код, ошибка исчезла.