Forum: PC-Programmierung saubere Declaration in C# und NameTypes


von danc (Gast)


Lesenswert?

Hi,

ich benötige in meiner Foreach schleife einen Index, dazu habe ich das 
ganze durch einen "Selector" im IEnumerable erweitert.
1
foreach (var datum in data.Select((value, i) => (value, i)))
2
{
3
    dataRow.Row[cells[datum.i]] = datum.value;
4
}

ich mag aber var nicht und möchte das Sauber durchdeclariert haben

also habe ich das var durch ValueTulpe ersetzt
1
foreach (ValueTuple<string, int> datum in data.Select((value, i) => (value, i)))
2
{
3
    dataRow.Row[cells[datum.Item2]] = datum.Item1;
4
}

leider kann ich jetzt nicht mehr auf meine variablen "i" und "value" 
zugreifen sondern muss auf Item1 und Item2 zugreifen, das ist vermutlich 
in der ValueTuple so vorgesehen.
Weiß jemand wie man das heilen / umgehen kann?

Vielen Dank
cheers

von nicht"Gast" (Gast)


Lesenswert?

danc schrieb:
> Hi,
>
> ich benötige in meiner Foreach schleife einen Index, dazu habe ich das
> ganze durch einen "Selector" im IEnumerable erweitert.
> foreach (var datum in data.Select((value, i) => (value, i)))
> {
>     dataRow.Row[cells[datum.i]] = datum.value;
> }
>
> ich mag aber var nicht und möchte das Sauber durchdeclariert haben

Das ist sauber durchdeklariert. "var" sollte man dann einsetzen, wann 
immer es möglich ist. So kannst du den Typ ändern ohne dadurch alles 
ändern zu müssen.

wo
1
 
2
    List<string> someValue = new List<string>();
noch übersichtlich sein vermag ist das bei verschachtelten Sachen schon 
wieder anders
1
   List<string> fileList = GetFileList();

kann zum gibt zum Beispiel ein List<string> mit allen Dateien aus dem 
aktuellen Verzeichnis zurück.
Jetzt stellst du fest: Ups das sind aber viele. ich will keine 20s 
warten, bis er alle gefunden hat.
Lösung: Du arbeitest mit IEnumerable<string> und yield.

Wenn du var benutzt hast brauchst du warscheinlich nichts ändern außer 
deiner GetFileList(). Hast du den Typ dagegen explizit angegeben kannst 
du dich schon mal freuen auf viele Änderungen. Besonders, wenn du 
GetFileList() nicht nur einmal benutzt hast.

Um deine Frage noch zu beantworten:
1
foreach ((string value, int i) datum in data.Select((value, i) => (value, i)))

ist die Formulierung deiner Wahl. Evtl noch das Nuget Package 
System.ValueTuple hinzufügen, wenn du das nicht schon längst getan hast.

von Torben (Gast)


Lesenswert?

>Das ist sauber durchdeklariert. "var" sollte man dann einsetzen, wann
>immer es möglich ist. So kannst du den Typ ändern ohne dadurch alles
>ändern zu müssen.

Die Aussage halte ich für ein Gerücht. In einigen Repos ist es zum 
Beispiel untersagt, also ist es eher "Coding Rules" abhängig.

von Dirk K. (merciless)


Lesenswert?

nicht"Gast" schrieb:
> Das ist sauber durchdeklariert. "var" sollte man dann einsetzen, wann
> immer es möglich ist. So kannst du den Typ ändern ohne dadurch alles
> ändern zu müssen.

Vielleicht will man ja genau eine Typänderung mitbekommen
und gibt deswegen den Typ explizit an? Das halte ich für den
besseren Stil: Wozu hat man eine streng typisierte Sprache,
wenn man nur var/auto etc. verwendet?

var/auto etc haben ihre Existenzberechtigung. So spart man
sich in seltenen Fällen umständliche Casts, aber das sollte
die Ausnahme sein.

merciless

von nicht"Gast" (Gast)


Lesenswert?

Dirk K. schrieb:
> Vielleicht will man ja genau eine Typänderung mitbekommen
> und gibt deswegen den Typ explizit an? Das halte ich für den
> besseren Stil: Wozu hat man eine streng typisierte Sprache,
> wenn man nur var/auto etc. verwendet?

var/auto heben die strenge Typisierung ja nicht auf. Sie geben die 
Entscheidung für den Typ nur an den Compiler weiter und das ist erst mal 
nichts schlechtes.

ein
1
    var foo = new bar()

mach aus dem foo vom Typ her bar und nichts anderes.
1
    foo="Hallo Welt"
später meckert der Compiler an. Da man einen string nicht foo zuweisen 
kann.


Grüße

von nicht"Gast" (Gast)


Lesenswert?

Dirk K. schrieb:
> var/auto etc haben ihre Existenzberechtigung. So spart man
> sich in seltenen Fällen umständliche Casts, aber das sollte
> die Ausnahme sein.

Sry, für den zweiten Post. Du hast var/auto nicht verstanden. Das hat 
mit typ casts nichts am Hut

von Dirk K. (merciless)


Lesenswert?

nicht"Gast" schrieb:
> Sry, für den zweiten Post. Du hast var/auto nicht verstanden. Das hat
> mit typ casts nichts am Hut

Ja dann benutze doch weiterhin var.
Ich habe mich ausgiebig mit Software-Architektur
auseinandergesetzt, ich benutze es nicht.

merciless

von nicht“Gast“ (Gast)


Lesenswert?

Dirk K. schrieb:
> Ja dann benutze doch weiterhin var.
> Ich habe mich ausgiebig mit Software-Architektur
> auseinandergesetzt, ich benutze es nicht.
>
> merciless

Etwas nicht zu wissen ist kein Grund pissig zu werden.

Grüße

von mh (Gast)


Lesenswert?

Dirk K. schrieb:
> Ich habe mich ausgiebig mit Software-Architektur
> auseinandergesetzt, ich benutze es nicht.

Und was hat var/auto mit Softwarearchitektur zu tun?

von Dirk K. (merciless)


Lesenswert?

mh schrieb:
> Und was hat var/auto mit Softwarearchitektur zu tun?

Wenn ich eine Klassenstruktur entwerfe und dann
excessiv var benutze, kann ich mir das schenken.
Da kann man genauso anonyme Datentypen on-the-fly
erzeugen, geht doch viel schneller und ist flexibel.
</sarcasm>

Es gibt Sprachen, da ist sowas möglich:
1
var x = "bla"; 
2
console.log(x);
3
4
x = function() {
5
  return 42;
6
}; 
7
console.log(x());
8
9
x = 4711; 
10
x++; 
11
console.log(x);
Das mag schick sein für Leute, die quick & dirty
irgendwas hinrotzen müssen oder für jeden Variablennamen
Geld bezahlen müssen, wartbarer Code ist das aber nicht.

merciless

von mh (Gast)


Lesenswert?

Dirk K. schrieb:
> [...]
Ob man "sowas" in irgendeiner anderen Sprache machen kann, ist kein 
relevantes Argument. Auch wenn es relevant wäre, beantwortet es die 
Frage nicht wirklich.

von nicht“Gast“ (Gast)


Lesenswert?

Nun geht's hier vor allem um C# und nicht JS.

Bei C# sagt var dem Compiler nur, das er den Typ selber festlegen darf. 
Er ist danach nicht mehr änderbar und steht zur Compilezeit fest.

C# ist statisch typisiert und var ändert nix daran.

Du bist im falschen Thread.

Grüße

von Dirk K. (merciless)


Lesenswert?

nicht“Gast“ schrieb:
> Du bist im falschen Thread.
Du hast nicht verstanden, was ich geschrieben habe.

merciless

von Dirk K. (merciless)


Lesenswert?

mh schrieb:
> Dirk K. schrieb:
>> [...]
> Ob man "sowas" in irgendeiner anderen Sprache machen kann, ist kein
> relevantes Argument. Auch wenn es relevant wäre, beantwortet es die
> Frage nicht wirklich.
Die Frage wird beantwortet im Absatz vor dem JS-Beispielcode.

merciless

von mh (Gast)


Lesenswert?

Dirk K. schrieb:
> mh schrieb:
>> Dirk K. schrieb:
>>> [...]
>> Ob man "sowas" in irgendeiner anderen Sprache machen kann, ist kein
>> relevantes Argument. Auch wenn es relevant wäre, beantwortet es die
>> Frage nicht wirklich.
> Die Frage wird beantwortet im Absatz vor dem JS-Beispielcode.
>
> merciless

Das war ernst gemeint? Warum dann der "Sarkasmus? Und wenn du glaubst, 
dass das die Antwort ist, hast du wirklich keine Ahnung was var/auto 
ist.

von Dirk K. (merciless)


Lesenswert?

mh schrieb:
> Warum dann der "Sarkasmus?

Seit der Einführung von var gibt es Diskussionen
um die Sinnhaftigkeit. Für mich gibt es 2 Nachteile,
die die Vorteile in jedem Fall überwiegen:

schlechte Lesbarkeit:
Ich kann nicht erkennen, welchen Typ die Variable
bekommt. Kann ausgeglichen werden durch vernünftige
Namensgebung. Da aber var meist dort eingesetzt wird,
wo Tastendrücke Geld kosten, heißen die Variablen
meistens x oder i.

Erkennung von Veränderungen:
Wird der Rückgabewert einer Funktion geändert, wird
das durch var nicht ersichtlich. Der Compiler
benutzt den neuen Typen. Das kann gut gehen oder auch
nicht, Fehlermöglichkeiten werden verschleiert.

Ich habe in meinem Leben genug schlechten Code
lesen müssen. var verringert in meinen Augen die
Wartbarkeit erheblich.

merciless

von mh (Gast)


Lesenswert?

Das sind zwei gute Argumente gegen var/auto, aber sie haben beide nichts 
mit Architektur zu tun.

von Dirk K. (merciless)


Lesenswert?

mh schrieb:
> Das sind zwei gute Argumente gegen var/auto, aber sie haben beide nichts
> mit Architektur zu tun.
Gut, hätte ich mich detaillierter ausdrücken müssen:
Eine gute Software-Architektur geht bei mir einher mit
der Einhaltung von Coding-Styleguides und Clean-Code-
Prinzipien. Als Architekt bin ich dafür verantwortlich,
die Umsetzung meines Entwurfes zu überwachen. Üblicherweise
werden Vorgaben für das Coding auch vom Architekten gemacht
(bzw. ganzen Teams davon in größeren Projekten). In einem
Review würde ich Code ablehnen, wenn er nicht leicht
verständlich ist.

Stichworte zum Suchen: Wartbarkeit, Veränderbarkeit, Sicherheit
https://de.wikipedia.org/wiki/Softwarearchitektur
https://de.wikipedia.org/wiki/Programmierstil

merciless

von nicht“Gast“ (Gast)


Lesenswert?

Dirk K. schrieb:
> Du hast nicht verstanden, was ich geschrieben habe.
>
> merciless

Doch habe ich, das hat aber mit den Thread hier gar nichts zu tun. Du 
parlierst über Birnen, wo wir hier von Äpfeln reden.

Die Frage von TO habe ich bereits beantwortet und zusätzlich den Hinweis 
gegeben, dass var in C# ruhig eingesetzt werden kann und es auch 
begründet.

Wenn dir var suspekt ist, dann ist das deine eigene Sache.

Das var in anderen Sprachen (welche war das nun eigentlich? ) andere 
Bedeutungen hat hat hier auch nichts zu suchen.

von nicht“Gast“ (Gast)


Lesenswert?

Ich muss mich wirklich irgend wann mal anmelden, damit ich Beiträge 
editieren kann.

Dirk K. schrieb:
> https://de.wikipedia.org/wiki/Softwarearchitektur
> https://de.wikipedia.org/wiki/Programmierstil

Die fällt auf, das es zwei getrennte Links sind und in dem einen nicht 
der andere referenziert wird? Die beiden Themen betreffen zwar das 
gleiche, haben aber direkte Korrelation.

Grüße

von Jonas B. (jibi)


Lesenswert?

Der Datentyp ergibt sich bei C# ja aus der rechten Seite:

var listeOfString = new List<string>();

Warum sollte ich ihn also nochmal auf der linken Seite anführen müssen?
Das ist mehr so als "Hier Compiler such dir mal den Ausdruck für den 
Datentyp selbst aus" gedacht und macht durchaus Sinn. Die C++ Syntax mit 
auto&& usw. find ich persönlich erstmal wenig intuitiv...

von mh (Gast)


Lesenswert?

Jonas B. schrieb:
> Die C++ Syntax mit
> auto&& usw. find ich persönlich erstmal wenig intuitiv...

Vermutlich weil du von C# Referenz- und nicht Wertsemantik gewöhnt bist?

von Torben (Gast)


Lesenswert?

1
foreach (var datum in data.Select((value, i) => (value, i)))
2
{
3
    dataRow.Row[cells[datum.i]] = datum.value;
4
}
1
foreach (ValueTuple<string, int> datum in data.Select((value, i) => (value, i)))
2
{
3
    dataRow.Row[cells[datum.Item2]] = datum.Item1;
4
}

Ich würde den Query und die foreach schleife trennen aus den folgenden 
Gründen:

1. Fehlerbehandlung, wenn der Query null ergibt.
2. Debugging des Codes
3. Lesbarkeit
4. Ob ich nun den Query in eine anonyme Type oder eine .net Type mache 
kommt auf dem Use case an.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.