Czy piszecie słowo this w metodach?

1

Powiedzmy, że mamy prostą klasę i mamy wybrać czy i kiedy używamy słowa kluczowego, które odnosi się do bieżącej instancji. Można w ogóle nie pisać:

public class Person {
	private String name, surname;

	private void metoda() {}

	private void dupa() {
		metoda();
	}

	public String getName() {
		return name;
	}

	public void setName(String name_) {
		name = name_;
	}

	public String getSurname() {
		return surname;
	}

	public void setSurname(String surname_) {
		surname = surname_;
	}

}

Można też zapisać z użyciem this (albo self czy czegoś w tym stylu).

public class Person {
	private String name, surname;

	private void metoda() {}

	private void dupa() {
		this.metoda();
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSurname() {
		return surname;
	}

	public void setSurname(String surname) {
		this.surname = surname;
	}

}

Czy może macie jeszcze inne rozwiązanie?

3

Tylko w konstruktorach ew. setterach jak już je pisze bo tak ktoś wybrał :/

0

W C# używam nie powszechnej ale dosyć często spotykanej konwencji zaczynania nazw pól od podkreślnika (czy jak to się tam zwie). Do właściwości nie używam nic. A więc z this nie korzystam wcale.

class SomeHandler
{
  private readonly IRepository _repository;

  public SomeHandler(IRepository repository)
  {
    _repository = repository;
  }
}
6

Im mniej kodu i znaków tym lepiej (oczywiście w granicach rozsądku) dlatego nie pisze this

9

Tylko gdy argument koliduje z polem

11

Używam bo w PHP muszę.

7

a ja staram sie pisać coby łatwiej potem odczytać kod

1

Tylko w konstruktorach.
W setterach nie piszę bo ich nie mam, ewentualnie jak już są to generuje je lombok.
W każdym innym miejscu nie używam. Od wskazywania, że czy użyta nazwa jest atrybutem obiektu czy lokalnie zadeklarowaną zmienną jest IDE.

7

Używam, self :-D

2
Miang napisał(a):

a ja staram sie pisać coby łatwiej potem odczytać kod

Chodzi Ci tylko o pola klas czy również metody? Jeśli również metody to w jaki sposób to ułatwia czytanie kodu Twoimi zdaniem?

5

W C++ this-> potrafi zmienić zachowanie kodu, przykładowo:

template<typename T>
struct Base {
  int answer() { return 42; }
};

template<typename T>
struct Deriv : Base<T> {
  int run() { return answer(); }
};

To się nie skompiluje, za to to:

template<typename T>
struct Base {
  int answer() { return 42; }
};

template<typename T>
struct Deriv : Base<T> {
  int run() { return this->answer(); }
};

Już jak najbardziej tak.

4

W js nie da się inaczej :)

1

Używam w konstruktorze lub w metodach z klasy, z której dziedzicze. W ten sposób wiem skąd pochodzi dana metoda

8

Jestem formalistą więc używałem i używam zawsze :-)
Nie lubię skrótów myślowych w kodzie źródłowym... Takie przyzwyczajenie a może "starcze" dziwactwo.
Uważam jednak, że to ułatwia czytanie kodu, szczególnie komuś kto czyta kod z języka, który nie jest jego "podstawowym".

Nawet w Delphi używałem w PHP muszę w JavaScript w starym zapisie chyba też było to konieczne a nawet self zrzutowane na var self = this;
W nowym ES6 nawet nie wiem czy jest wymagane ale też używam.

6

Tak, jak pisali powyżej chociażby @Miang czy @katakrowa - zawsze staram się to stosować, nawet jeśli nie jest to wymagane. Bo dodanie tych kilku liter nie jest czymś, co będzie realnie odczuwalnym utrudnieniem podczas pisania, w żaden sposób nie ma to wpływu na prędkość kompilacji czy później działania aplikacji, a o tych kilkuset dodatkowych znakach w kodzie w ogóle nie ma co pisać bo to totalny absurd.

Odpowiadając na pytanie @Aventus - czyli "w czym to pomaga":

  • jak masz clientHeight = screenHeight to co tak naprawdę wiesz? Po pierwsze - można podejrzewać, że clientHeight jest czymś należącym do klasy, ale może np. ktoś trzasnął jakąś zmienną globalną? :P
  • idąc dalej - ustalamy, że na pewno clientHeight należy do klasy (czyli dałoby się zapisać w postaci this.clientHeight). W takim razie wiemy, że do pola clientHeight podstawiamy screenHeight
  • ale ponownie - nie wiemy, czym to coś jest. Czy to jest funkcja, inna składowa naszej klasy, zmienną globalną albo czymś w jakiś inny sposób widocznym w naszym zakresie?
  • a zamieniając to na zapis this.clientHeight = this.screenHeight() od razu wiemy o co chodzi, na pierwszy rzut oka jest to czytelne. Do pola clientHeight należącego do klasy w której grzebiemy podstawiamy wartość zwróconą przez funkcję screenHeight, która także jest elementem tej samej klasy co clientHeight.

Poza tym - wprawdzie tego nie dotyczy wprost ten wątek, ale i tak dodam ;) :

  • nawet jeśli dany język tego nie wymaga, a funkcja nie ma żadnych argumentów/parametrów, to i tak daję pusty nawias przy wywołaniu funkcji. W ten sposób wiadomo, że do zmiennej podstawiamy wartość zwróconą przez funkcję, a nie inną zmienną
  • nawiasy w przypadku if i innych podobnych strukturach: można napisać if (a > b && jakisBool) (zapis przykładowy, może w rożnych językach jest inna kolejność, ale przyjmijmy że tutaj mamy ważniejsze porównanie, a potem dopiero iloczyn). To samo można napisać if ((a > b) && jakisBool) - przy założeniu podanym w nawiasie, efekt będzie dokładnie taki sam, ale dla mnie jest to czytelniejsze, nie ma nawet chwili zastanowienia się jak to się będzie ewaluować.

Oczywiście - bez tych "sztuczek" także da się zrozumieć co zostało napisane, ale czasem może być (przy bardziej złożonych konstrukcjach) potrzebna chwila na zastanowienie, a po drugie - czasem kod czyta ktoś mniej biegły, kto nie zna dobrze danej technologii itp. No i jeszcze jest taka sprawa, że mając te nawiasy, trudniej jest popełnić błąd, coś źle wstawić itp.

Trzeba pamiętać, że tak naprawdę kod się pisze dla innych ludzi a nie kompilatora. Jakby chodziło tylko o kompilator to byśmy nie tworzyli opisowych nazw zmiennych (bo a1, a2, b1, b2 itp. by działały dokładnie tak samo), nie stosowali wcięć, rozbijania na wiele plików (dawaj Pan całą apkę do main.c) i połowy z rzeczy, które są uważane za "dobre praktyki". Ale to robimy - po to, żeby inni programiści (albo my sami za parę miesięcy) mogli łatwo odczytać co autor miał na myśli. I to this, nawiasy itp. właśnie to ułatwiają.

5

Prywatnie tak, zawodowo zależy od konwencji w projekcie.

1

Ja nie pisze niepotrzebnego kodu. this. w miejscu gdzie nie jest to konieczne to niepotrzebny kod - niepotrzebny, bo bez niego program działałby tak samo. Używam go tylko w dwóch przypadkach:

  • chcę gdzieś przekazać referencje do aktualnego obiektu, wtedy przekazuje this
  • pole i zmienną lokalna nazywają się tak samo, wtedy używam this, żeby je rozróżnić.

Ps: jeśli ktoś mi wyjedzie i powie "używanie pół bez this jest nieczytelne" mam odpowiedź - naucz się języka, bo takie gadanie wynika z nieznajomości języka programowania, albo ewentualnie z wielkich klas których się nie da zrozumieć. A do osób które powiedzą "u mnie w firmie mamy wielkie klasy których nie mogę zmienić" - wrong, możesz, tylko musisz dobrze znać język programowania i widzieć co robisz.

4

W Javie w kodzie firmowym tylko jak jest konflikt ze zmienną lokalna bo taka jest konwencja w projektach. W Rust zawsze self bo trzeba i dzięki temu nie ma wątpliwości jak należy pisać i programiści nie tracą czasu na dyskusje o szczegółach stylistycznych.

7

niepotrzebny, bo bez niego program działałby tak samo

Oczywiście - tak samo się skompiluje i później wykona.
Więc proponuję też rezygnację z wcięć, opisowych nazw zmiennych i funkcji (a, b, c, d a jak się skończą to wariacje w stylu aa1, aba, bac) i innych rzeczy zgodnych z tzw. "clean code" i dobrymi praktykami.

Przecież to nie chodzi o to, czy to this jest potrzebne ze względu na kompilator, ale mamy sobie tym życie ułatwiać.

używanie pół bez this jest nieczytelne" mam odpowiedź - nacz się języka, bo takie gadanie wynika z nieznajomości języka

Ok, Ty to wiesz, pewnie większość z osób tutaj piszących także sobie bez tego poradzi. Ale to nie znaczy, że z tym this nie jest to bardziej czytelne. Poza tym - możesz mieć w projekcie kogoś z mniejszym doświadczeniem, jakiegoś juniora itp. i tej osobie to może pomóc zrozumieć kod, a może i uniknąć błedu. Zresztą - w wielu branżach mamy określone procedury postępowania. Taki pilot samolotu mimo tego, że lata od 30 lat, i tak musi przejść całą ścieżkę przed startem (chociaż w dużej mierze jest to nadmiarowe). Tak samo maszynista - co chwilę musi wciskać przycisk potwierdzający, że nie zasnął. Takich procedur bezpieczeństwa w róznych sytuacjach jest pełno, a dla mnie dodanie this jest właśnie czymś takim - w niczym totalnie nie przeszkadza (bo wybacz, ale nie uważam tych kilku dodatkowych znaków do wpisania za jakiekolwiek utrudnienie), a może pomóc. Więc nic nie tracisz, a możesz mieć jakiś zysk - głupio nie skorzystać.

2

Dałem okejkę dla posta @cerrato nie dla tego że się zgadzam ale za rzeczową odpowiedź. Tak naprawdę to podkreśliła ona że debata "this czy nie this" bez uwzględnienia jednego, konkretnego języka trochę nie ma sensu. Ja pisałem w kontekście C#, ale ewidentnie to naprawdę zależy od konkretnego języka (gdzie np. w takim JS bez this się nie obędzie co już zostało wspomniane wcześniej). Odnosząc się do postu cerrato aby podeprzeć moją tezę:

jak masz clientHeight = screenHeight to co tak naprawdę wiesz? Po pierwsze - można podejrzewać, że clientHeight jest czymś należącym do klasy, ale może np. ktoś trzasnął jakąś zmienną globalną?

W C# nie ma czego takiego jak zmienne globalne.

idąc dalej - ustalamy, że na pewno clientHeight należy do klasy (czyli dałoby się zapisać w postaci this.clientHeight). W takim razie wiemy, że do pola clientHeight podstawiamy screenHeight

Punkt wyżej.

ale ponownie - nie wiemy, czym to coś jest. Czy to jest funkcja, inna składowa naszej klasy, zmienną globalną albo czymś w jakiś inny sposób widocznym w naszym zakresie?

Punkt wyżej oraz dodatkowo to zależy od konwencji języka (Które oczywiście ktoś może łamać). W C# nazwy metod zgodnie z konwencją zaczynają się od dużych liter, zmiennych nie. Rozróżnienie jest więc łatwe Właściwości co prawda również zaczynają się od dużych liter, ale tutaj ułatwieniem jest forma nazewnictwa- właściwości w odróżnieniu od metod (znów- zgodnie z konwencją) nie mają wydźwięku nakazującego, np. Calculate..., Get..., Build... itp.

Nie piszę tego przeciwko używaniu this bo tak jak już wspomniałem- to całkowicie zależy od konkretnego języka.

Raz jeszcze w kontekście C# to naprawdę tylko kwestia preferencji. Moja preferencja jest taka że nie ma potrzeby z tego korzystać więc tego nie robię, inni (np. @somekind) uważają inaczej. I to w zasadzie tyle.

EDIT: Dodam jeszcze że raz pracowałem w projekcie gdzie dla pól ani nie używano this, ani nie używano podkreślnika. Z dwojga "złego" zdecydowanie już wolał bym używać this niż nie używać nic, bo wtedy kod jest zdecydowanie mniej czytelny:

void DoSomething()
{
  // ...
  finalResult = currentResult + someValueToAdd; // Które z tych to pola, a które to zmienne lokalne?
}
0

Tak, @Aventus słusznie zauważyłeś, że w różnych językach to różnie bywa. I z automatu bym olał te, w których jest to obowiązkowe, bo tam się po prostu daje i nie ma dyskusji.

W C# nazwy metod zgodnie z konwencją zaczynają się od dużych liter, zmiennych nie. Rozróżnienie jest więc łatwe

Konwencja to jest jedynie zbiór dobrych praktyk/zaleceń, więc może ktoś się pojawić, kto to zignoruje, się pomyli, albo nie będzie o tym wiedział. I teraz, paradoksalnie, bez tego this możesz przyjąć błędne założenie - bo zastosowany sposób nazywania elementów będzie sugerować jedną wersję, ale naprawdę będzie to coś innego (tylko nazwane niezgodnie z tą konwencją) :P

1

@cerrato: to prawda, ale zakładam że odstępy od normy zostaną wyłapane na etapie code/peer review. Może w wyidealizowanym świecie żyje :P

Oraz taka ciekawostka dla niektórych- jeśli chodzi o konwencje typu nazewnictwo metod oraz właściwości to w przypadku C# jest to naprawdę raczej standard.

2

@Aventus:

Z dwojga "złego" zdecydowanie już wolał bym używać this niż nie używać nic, bo wtedy kod jest zdecydowanie mniej czytelny:

void DoSomething()
{
  // ...
  finalResult = currentResult + someValueToAdd; // Które z tych to pola, a które to zmienne lokalne?
}

Nie macie kolorowania składni w VisualStudio czy w czym się tam aktualnie programuje C#? :P

screenshot-20211030223746.png

0

Prywatnie nie używam. Zawodowo, zależy od konwencji i pobliskiego kodu.

2

@Grzyboo: akurat kolorowanie składni to słaby argument bo to może się diametralnie różnić nie tylko między IDE ale również w zależności od motywu jaki programista używa w jednym IDE.

Paradoksalnie, choć zazwyczaj promuję różne nowości języka czy też framework'a, to nie lubię obecnego trendu nadmiernego kolorowania składni gdzie każdy typ/rodzaj kodu ma inny kolor itp. Jak dla mnie to wprowadza zbyt wiele zamieszania. No ale jak wcześniej wspomniałem, to kwestia osobistych preferencji :)

0
cerrato napisał(a):

Ok, Ty to wiesz, pewnie większość z osób tutaj piszących także sobie bez tego poradzi. Ale to nie znaczy, że z tym this nie jest to bardziej czytelne.

No niby tak, ale dla mnie to niepotrzebny kod. Z this. działa, bez niego też działa. Niepotrzeny kod. Tak samo widzę == True, int + 0, albo int * 1. Czy można je dodać, tak żeby program nadal dział? Tak. Czy jest to potrzebne? Nie.

Poza tym - możesz mieć w projekcie kogoś z mniejszym doświadczeniem, jakiegoś juniora itp. i tej osobie to może pomóc zrozumieć kod, a może i uniknąć błedu.

Na to mam inną odpowiedź. Lepiej podnosić skille juniorów do poziomu projektu, niż zaniżać poziom projektu do skilli juniorów.

Dla juniora kod if (user.active == true) jest czytelniejszy, spora część z resztą pisze taki. Ale czy to jest powód żeby używać tego w projekcie? Ja nigdy nie pozwoliłbym na == True w projekcie, jeśli powodem jest to że "dla juniora to jest czytelniejsze". Podobnie nie zezwoliłbym na this, jeśli powód jest ten sam. Oczywiście powody dla tych konstruktów mogą być inne - ja się staram tylko zilustrować ze argument "bo dla juniora może być cięższe" jest nieadekwatny.

Oczywiście, powinniśmy dbać o czytelność kodu i readibilty. Ale dodawanie redundatnych kawałków kodu jak this albo == True to nie jest droga do tego moim zdaniem.

2

this. działa, bez niego też działa.

Tak samo jak wspomniane już wcześniej opisowe nazwy i wcięcia :P

int + 0, albo int * 1

OK, to jest bzdura... ale nigdy się z czymś takim nie spotkałem. Czy możesz przybliżyć okoliczności, w których ktoś mógłby chcieć z takich konstrukcji korzystać?

if (user.active == true)

Tutaj trochę się kłania kwestia nazw zmiennych. W tej postaci jest to OK, ale moim zdaniem to jest to błędnie nazwane. Ja bym dał if (user.isActive) i wtedy ten fragment z równa się oraz true byłby zbędny. Ale w podanym przez Ciebie przykładzie to go rozumiem i nie jest niczym rażącym.

2

@cerrato zapominasz (a @hauleth zdaje się tego nie podkreślać) o konwencjach nazewniczych. U mnie w projektach z reguły zacznijOdMalej to metody, m_nazwa to pola, ZacznijOdDuzej to static methods a STALA to const/constexpr. I wtedy ten this jest faktycznie staje się hałasem. Co do == true tak samo się zgadzam z @hauleth
Tylko potem MISRA expert przyjdzie i powie, że safety, VW, BMW, Volvo i ogólnie weź to pisz bo explicit true i better explicit. Jest to podwójnie śmieszne kiedy zamiast static_cast<bool> ktoś wpisał w coding standard !!3, no ale co zrobisz jak nic nie zrobisz ;P

5

Do obroncow this: A dlaczego piszecie new Foo() zamiast new com.example.company.duper.super.library.Foo(). Przeciez nawet nie wiadomo skad ta klasa sie bierze?! XD

1

Nie piszę this jeśli nie muszę, a muszę rzadko. Poza tym explicit nie zawsze jest lepsze niż implicit, jak się ludzie przyzwyczaja do pisania niepotrzebnego kodu to im się później wydaje że inaczej się nie da, nie będzie działać albo będzie działać inaczej - np. wywołanie bezparametrowego konstruktora klasy bazowej w C# może być implicit lub explicit, ale przyzwyczajenie się do pisania tego może budować mylne wrażenie, że bez tego base() konstruktor się nie wywoła. Podobny syf jak pisanie pustych konstruktorów, bo to też przecież jest explicit, zamiast polegania na konstruktorze domyślnym.

1 użytkowników online, w tym zalogowanych: 0, gości: 1