Вы можете добавить this()
в свой конструктор или заменить авто-свойства свойствами, поддерживаемыми полем.
public Rational(long num, long den)
{
// and here (GCD is underline) the 4. error
long simple = GCD(num, den);
this.Numerator = num;
this.Denominator = den;
}
Здесь вы получаете доступ к методу экземпляра GCD
до того, как назначаетезначение для автоматически сгенерированных полей, поддерживающих ваши свойства.
Вы должны сделать этот метод статическим.
Далее вы снова получите ту же ошибку, на этот раз, потому что вы получаете доступ к свойству auto Numerator
.Вы можете исправить это, сохранив автоматические свойства и добавив :this()
в конструктор:
public Rational(long num, long den)
:this()
{
В результате поля будут инициализированы в 0
до запуска собственного кода конструктора.
Альтернативой является переключение на поля:
public struct Rational : IComparable<Rational>
{
private long _numerator;
private long _denominator;
public long Numerator { get{return _numerator;}; set{_numerator=value;} }
public long Denominator{ get{return denominator;}; set{_denominator=value;} }
public Rational(long num, long den)
{
// and here (GCD is underline) the 4. error
long simple = GCD(num, den);
this._numerator = num;
this._denominator = den;
}
Помимо этого в вашем коде есть еще несколько проблем:
1) Вы используете изменяемую структуру.Это обычно плохой дизайн.Удалите сеттер из ваших свойств или сделайте его приватным.
2) Вы не переопределяете GetHashCode()
, чтобы соответствовать Equals
(или это просто не показано в вашем фрагменте кода)
3) Я рекомендую реализовать IEquatable<Rational>
.Вы уже внедрили Equals(Rational)
, поэтому вам не нужно добавлять никаких дополнительных методов.
4) Ваш код очень легко производит переполнение int.Подумайте об использовании BigInteger
с вместо long
с.
5) Если вы не нормализуете свой рациональный (знаменатель> 0 и разделите оба на GCD), вы получите математически эквивалентные рациональные числа, которые не сравниваются как равные.