С#, используя это ключевое слово в этой ситуации?

Я выполнил задание курса ООП, где я разрабатываю и кодирую класс комплексных чисел. Для дополнительного кредита я могу сделать следующее:

  1. Сложите два комплексных числа. Функция примет один объект комплексного числа в качестве параметра и вернет объект комплексного числа. При добавлении двух комплексных чисел действительная часть вызывающего объекта добавляется к действительной части объекта комплексного числа, переданного в качестве параметра, а мнимая часть вызывающего объекта добавляется к мнимой части объекта комплексного числа, переданного как параметр.

  2. Вычтите два комплексных числа. Функция примет один объект комплексного числа в качестве параметра и вернет объект комплексного числа. При вычитании двух комплексных чисел действительная часть объекта комплексного числа, переданного в качестве параметра, вычитается из действительной части вызывающего объекта, а мнимая часть объекта комплексного числа, переданного в качестве параметра, вычитается из мнимой части объекта. вызывающий объект.

Я закодировал это и использовал ключевое слово this для обозначения текущего экземпляра класса, код для моего метода добавления приведен ниже, и мой метод вычитания выглядит аналогично:

 public ComplexNumber Add(ComplexNumber c)
{
    double realPartAdder = c.GetRealPart();
    double complexPartAdder = c.GetComplexPart();

    double realPartCaller = this.GetRealPart();
    double complexPartCaller = this.GetComplexPart();

    double finalRealPart = realPartCaller + realPartAdder;
    double finalComplexPart = complexPartCaller + complexPartAdder;

    ComplexNumber summedComplex = new ComplexNumber(finalRealPart, finalComplexPart);

    return summedComplex;
}

Мой вопрос: Сделал ли я это правильно и со вкусом? (используя это ключевое слово)?


person Alex    schedule 04.12.2009    source источник
comment
+1 за то, что задал вопрос о домашнем задании и показал, что вы приложили немало усилий, а не просто попросили людей решить его за вас. Продолжайте хорошую работу   -  person Matt    schedule 06.12.2009


Ответы (11)


Можно обсудить использование ключевого слова this, но обычно все сводится к личному вкусу. В данном случае, будучи избыточным с технической точки зрения, я лично считаю, что это добавляет ясности, поэтому я бы тоже использовал его.

person Fredrik Mörk    schedule 04.12.2009
comment
так что мне вообще не нужно это ключевое слово? мои методы get автоматически действуют на текущий экземпляр класса? - person Alex; 04.12.2009
comment
Правильно, оставьте это. префикс, и он будет использовать методы и свойства текущего экземпляра. - person Timothy Walters; 04.12.2009
comment
Это особенно хорошо, когда речь идет о коде, предназначенном для начинающих, поскольку делает цель оператора более явной. - person Romain; 04.12.2009
comment
Единственное место, где вы должны использовать это, - это когда у вас есть приватное поле и локальная переменная с тем же именем. Неквалифицированный компилятор выберет локальную переменную. Таким образом, следующий код должен квалифицировать его следующим образом: name = name; - person Lasse V. Karlsen; 04.12.2009
comment
Я имел в виду... единственное место, где требуется использовать это, я согласен с личным вкусом, поэтому я не имел в виду не использовать это в любом другом случае. - person Lasse V. Karlsen; 04.12.2009
comment
это не единственное место, где это требуется. если вы хотите вернуть текущий объект, вам нужно вернуть это, хорошим примером этого будет перегрузка оператора =, чтобы разрешить цепочку - person jk.; 04.12.2009
comment
Использование this здесь тоже излишне, просто посмотрите на имена переменных :-) - person ; 03.04.2010

Использование избыточного this. поощряется стандартами кодирования Microsoft, воплощенными в инструменте StyleCop.

person Steve Gilham    schedule 04.12.2009
comment
И это обескуражено Resharper. - person Carra; 04.12.2009
comment
И это обескураживает CodeRush. За что ненавижу. - person Vilx-; 04.12.2009
comment
И это не рекомендуется стандартом кодирования IDesign: 65. Не используйте эту ссылку, если не вызываете другой конструктор из конструктора. Вот как я это использую, и мне нравится подход R# по умолчанию. idesign.net/idesign/download/ - person Martin R-L; 04.12.2009

Вы также можете перегружать математические операторы, так же, как:

public static ComplexNumber operator +(ComplexNumber c1, ComplexNumber c2)
person Rubens Farias    schedule 04.12.2009

Поскольку сейчас вы изучаете C# и спрашиваете о стиле, я собираюсь показать вам несколько ошибок в коде, который вы разместили, а также причины.

Редактировать: я ответил на это только потому, что похоже, что вы действительно работаете над тем, чтобы разобраться в этом. Поскольку я предпочитаю работать с такими людьми, я более критичен просто потому, что надеюсь, что в результате это поможет вам стать лучше. :)

Название структуры

  1. ComplexNumber излишне длинный. Обратите внимание, что ни один из Single, Double, Int32, Int64 и т. д. не содержит Number в имени. Это предлагает Complex как более подходящее имя.
  2. Complex соответствует именованию, уже установленному в .NET Framework.

Реальные и мнимые компоненты

  1. GetRealPart() и GetComplexPart() должны быть свойствами только для получения, а не методами.
  2. GetComplexPart() имеет неправильное имя, потому что на самом деле возвращает мнимую часть.
  3. Поскольку структура .NET уже имеет структуру Complex, вам не следует заново изобретать имена. Поэтому, если вы не в состоянии переопределить соглашения Framework, свойства должны называться Real и Imaginary.

Операции

Если вы посмотрите на существующие примеры, такие как System.Windows.Vector вы видите, что математические операции реализуются с помощью статического метода и оператора:

public static Point Add(Vector vector, Point point);
public static Point operator+(Vector vector, Point point);

Неудивительно, что это соглашение было перенесено в System.Numerics.Complex структура:

public static Complex Add(Complex left, Complex right);
public static Complex operator +(Complex left, Complex right);

Резюме

Результат чистый, легко проверяемый и ведет себя так, как все ожидают. Ключевое слово this не появляется/не может появиться, потому что методы являются статическими.

public static Complex Add(Complex left, Complex right)
{
    return new Complex(left.Real + right.Real, left.Imaginary + right.Imaginary);
}

public static Complex operator +(Complex left, Complex right)
{
    return new Complex(left.Real + right.Real, left.Imaginary + right.Imaginary);
}
person Sam Harwell    schedule 03.04.2010

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

private String firstname;
public SetName(String firstname)
{
    this.firstname = firstname;
}
person Raj    schedule 04.12.2009
comment
Удобно, что этого никогда не происходит, потому что поля элементов всегда начинаются с _, а имена параметров никогда не начинаются с _. - person Sam Harwell; 03.04.2010

Я бы сказал да, это выглядит правильно и легко читается. Но разве это не то, на что должен ответить ваш ТА?

person Sune Rievers    schedule 04.12.2009
comment
это дополнительный балл, ТА и профессор не будут помогать в дополнительных баллах, даже не будут говорить с вами об этом. Что имеет смысл, я думаю. - person Alex; 04.12.2009

double realPartCaller = this.GetRealPart();

Даже если вы опустите this из GetRealPart(), все равно все будет в порядке. Но использование this упрощает чтение и понимание, когда дело доходит до сопровождающего.

double realPartCaller = this.GetRealPart(); ==> bit more readable IMHO
double realPartCaller = GetRealPart();
person aJ.    schedule 04.12.2009

Я все чаще и чаще использую ключевое слово this как для методов, так и для свойств текущего экземпляра, так как чувствую, что это повышает читабельность и удобство сопровождения. это особенно полезно, если ваш класс также имеет статические методы и/или свойства, для которых вы, конечно, не можете использовать ключевое слово this, так как они не связаны с текущим экземпляром. Используя this, вы ясно видите разницу.

Чтобы продвинуться еще дальше, вы должны рассмотреть возможность использования имени класса в качестве квалификатора для статических методов и свойств, даже внутри самого класса.

person HKalnes    schedule 04.12.2009

Просто чтобы добавить полноты ответам - есть один случай, когда ключевое слово this является обязательным. Это когда у вас есть локальная переменная (или параметр метода), имя которой совпадает с именем члена класса. В этом случае его запись без this приведет к доступу к локальной переменной, а с this установит член класса. Проиллюстрировать:

class MyClass
{
    public int SomeVariable;

    public void SomeMethod()
    {
        int SomeVariable;

        SomeVariable = 4; // This assigns the local variable.
        this.SomeVariable = 6; // This assigns the class member.
    }
}

Пара вещей, которые следуют из этого:

  • Всегда избегайте давать локальным переменным то же имя, что и членам класса (признаюсь, я сам не всегда следую этому);
  • Написание this перед доступом всех членов действует как защита. Если вы напишете кусок кода без него, а затем позже введете локальную переменную с тем же именем и типом, что и у члена класса, ваш код по-прежнему будет нормально компилироваться, но будет делать что-то совершенно другое (и, вероятно, неправильное).

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

class MyClass
{
    public int VariableA;
    public string VariableB;

    public MyClass(int VariableA, string VariableB)
    {
        this.VariableA = VariableA;
        this.VariableB = VariableB;
    }
}

На мой взгляд, это делает конструктор более понятным, потому что вы сразу понимаете, какой параметр устанавливает какой член класса.

person Vilx-    schedule 04.12.2009

Использование этого ключевого слова выглядит нормально.

Хотя я считаю, что для такого класса, как Complex, вы должны хранить реальную и сложную часть как свойства int и использовать их в методе, а не использовать методы GetRealPart() и GetComplexPart()

Я бы сделал это так:

    class ComplexNumber
    {
        public int RealPart { get; set; }
        public int ComplexPart { get; set; }

        public ComplexNumber(int real, int complex)
        {
            this.RealPart = real;
            this.ComplexPart = complex;
        }

        public ComplexNumber Add(ComplexNumber c)
        {
            return new ComplexNumber(this.RealPart + c.RealPart, this.ComplexPart + c.ComplexPart);
        }
    }

Ниже приведен сценарий, в котором это ДОЛЖНО использоваться, в противном случае параметр, а не член класса, рассматривается как для левой, так и для правой стороны назначения.

public ComplexNumber(int RealPart, int ComplexPart)
        {
            RealPart = RealPart; // class member will not be assigned value of RealPart
            ComplexPart = ComplexPart;
        }
person SO User    schedule 04.12.2009

Если вы следуете соглашениям об именах, использование этого обязательно:

class MyClass 
{ 
    public int _variableA; 
    public string _variableB; 

    public MyClass(int variableA, string variableB) 
    { 
        _variableA = variableA; 
        _variableB = variableB; 
    } 
}
person Daniel    schedule 03.04.2010