Ошибки компиляции в C # struct - PullRequest
0 голосов
/ 06 ноября 2011

Это домашняя работа, и мы не изучаем структуры в C # (а я учусь сейчас).Поэтому я перехожу к MSDN, но я не вижу, в чем проблема моей программы ... Да, и я не могу перевести полностью назначенный для моего родного языка, и я не понимаю, что думает компилятор.

UML моей домашней работы: (мы должны ее использовать) Интерфейс: IComparable

  • + Числитель {get;}: long
  • + Знаменатель {get;}: long
  • + Rational (числитель: long, знаменатель: long)
  • + GCD (a: long, b: long): long
  • + Равно (r:Обоснование): bool
  • ...

И мы не должны реализовывать другие методы или параметры.

Я пишу эту домашнюю работу наJava с классами, которые работают правильно.

У меня большая проблема, я не понимаю, что означают следующие ошибки:

Ошибка 2 Поле поддержки для автоматически реализуемого свойства 'Rational.Rational.Знаменатель 'должен быть полностью назначен до того, как управление будет возвращено вызывающей стороне.Рассмотрите возможность вызова конструктора по умолчанию из инициализатора конструктора.

Ошибка 3 Поле поддержки для автоматически реализуемого свойства 'Rational.Rational.Numerator' должно быть полностью назначено до того, как управление будет возвращено вызывающей стороне.Попробуйте вызвать конструктор по умолчанию из инициализатора конструктора.

Ошибка 4 Объект 'this' нельзя использовать, пока все его поля не присвоены

my code: namespace Rational

{
    //       (Rational is underline)     here the 2 and 3 error
    public struct Rational : IComparable<Rational>
    {
        public long Numerator { get; set; }
        public long Denominator { get; set; }

        public Rational(long num, long den)
        {
             // and here (GCD is underline) the 4. error
            long simple = GCD(num, den);
            this.Numerator = num/simple;
            this.Denominator = den/simple;
        }

        public long GCD(long a, long b)
        {
            long c = Math.Abs(a);
            long d = Math.Abs(b);
            if (d == 0) return c;
            return GCD(d, c % d);
        }

        public override string ToString()
        {
            if (Denominator==1)
            {
                return Numerator + "";
            }
            return Numerator+"/"+Denominator;
        }

        public override bool Equals(object obj)
        {
            bool result = false;
            if (obj is Rational)
            {
                Rational r = (Rational)obj;
                result = this.Equals(r);
            }
            return result;            
        }

        public bool Equals(Rational r)
        {
            if ((object)r ==null)
            {
                return false;
            }
            return this.Denominator == r.Denominator && this.Numerator == r.Numerator;
        }

        public int CompareTo(Rational other)
        {
      ...

Ответы [ 4 ]

1 голос
/ 06 ноября 2011

Вам нужно вызвать конструктор по умолчанию, чтобы это работало:

public Rational(long num, long den) : this()
{
    // and here (GCD is underline) the 4. error
    long simple = GCD(num, den);
    this.Numerator = num;
    this.Denominator = den;
}

Большая проблема в том, что у вас изменяемая структура. Это никогда не хорошая идея. Я бы сделал это:

public long Numerator {get; private set;}
1 голос
/ 06 ноября 2011

Вы можете добавить 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), вы получите математически эквивалентные рациональные числа, которые не сравниваются как равные.

0 голосов
/ 06 ноября 2011

Сделайте вашу GCD статическую функцию.

Она не использует никаких элементов экземпляра, и потому что она вызывается до того, как установлены элементы экземпляра, она не может.

0 голосов
/ 06 ноября 2011

В вашем конструкторе для Rational я заметил, что вы вызываете GCD и сохраняете результат в simple, но вы не используете результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...