Autor Beitrag
erfahrener Neuling
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 233
Erhaltene Danke: 19

Win 7, Win 10
C#, ASP-MVC (VS 2017 Community), MS SQL, Firebird SQL
BeitragVerfasst: Mi 09.03.16 15:01 
Hallo,

Ich habe vor kurzem angefangen, mich mit xml zu beschäftigen und kenne mich nocht nicht gut aus.
Momentan schreibe ich ein Programm, welches SQL-Code in etwas anderes umwandeln soll.
Dabei habe ich folgendes Problem, dass ich einen Knotenpunkt ansteuern will, der aber nicht in jeder Zeile vorkommen muss.
D.h. wenn dieser Knotenpunkt nicht vorhanden ist, gibts eine Exception.
Mein Code dazu sieht so aus
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
try 
{
    MemberName = columnNode.SelectSingleNode("./@Member").Value;    //falls Member existiert, kein Problem
    Line += " ColumnName='" + MemberName + "'"; }
}    
catch (NullReferenceException) {}

Problem: seit ich das mit try-catch hinzugefügt habe, braucht der Process viel länger als ohne try-catch

Frage: Kann man das irgendwie lösen, in dem man vorher abfragt, ob 'Member' überhaupt vorhanden ist, a la
ausblenden C#-Quelltext
1:
if(columnNode.proofExistence("./@Member") {...}					

ohne dass eine Exception das ganze unnötig verlängert?

Gruß
Neuling
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 09.03.16 15:09 
Eine NullReferenceException ist immer ein Programmierfehler und sollte niemals per catch abgefangen werden.
In deinem Fall mußt du nur vorher prüfen, ob null zurückgeliefert wird, bevor du auf Value zugreifst, also
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
var node = columnNode.SelectSingleNode("./@Member");
if (node != null)
{
    MemberName = node.Value;
}

In C#6 kannst du auch mittels des ?.-Operators arbeiten:
ausblenden C#-Quelltext
1:
MemberName = columnNode.SelectSingleNode("./@Member")?.Value;					

MemberName hat dann, wenn der Knoten nicht gefunden wird, den Default-Datenwert von Value (d.h. bei einem string also null).

Für diesen Beitrag haben gedankt: erfahrener Neuling
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Mi 09.03.16 15:25 
user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
MemberName hat dann, wenn der Knoten nicht gefunden wird, den Default-Datenwert von Value (d.h. bei einem string also null).
Meines Wissens ist der Rückgabewert bei Verwendung von "?" ein Nullable des Grundtyps, das heißt wenn der Knoten nicht gefunden wird, ist der Rückgabewert null (was bei string natürlich keinen Unterschied macht, bei int aber z.B. schon ;-))

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
erfahrener Neuling Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 233
Erhaltene Danke: 19

Win 7, Win 10
C#, ASP-MVC (VS 2017 Community), MS SQL, Firebird SQL
BeitragVerfasst: Mi 09.03.16 15:45 
Super! Genau das hab ich gebraucht.. hatte gar nicht mehr auf das .Value geachtet, aber so machts natürlich Sinn
erfahrener Neuling Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 233
Erhaltene Danke: 19

Win 7, Win 10
C#, ASP-MVC (VS 2017 Community), MS SQL, Firebird SQL
BeitragVerfasst: Mi 09.03.16 16:02 
Hab doch noch ne Frage

die Datei hat folgenden Aufbau:
ausblenden XML-Daten
1:
2:
3:
4:
5:
6:
7:
<?xml version="1.0" encoding="utf-8"?>
<Database Name="..." Class="...">
  <Connection ... />
  <Table Name="dbo.ADRESSEN" Member="Adressen">
      .
      .
      .

Frage: Wie komme ich an die Kopfzeile per xml-Befehl? per selectNode klappt es jedenfalls nicht
Frage 2: Wieso klappt es nicht, was ist besonders an dieser Zeile?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 09.03.16 16:52 
@Christian: wir beide hatten nicht komplett recht ;-)

Bei Wertetypen wird ein Nullable<T> zurückgegeben, bei Referenztypen aber bleibt es so (denn Nullable<T> gibt es nur bei Wertetypen):
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
using System;

public class Test
{
  class A
  {
    internal int x;
    internal string y;
  }
  
  public static void Main()
  {
    A a = null;
    
    int? x = a?.x;
    string y = a?.y; // string? gibt Compiler-Fehler...
    
    Console.WriteLine(x);
    Console.WriteLine(y);
  }
}

Bei Wertetypen ist also der ?.-Operator genauso unelegant, wie das Prüfen auf null, da man dann anschließend beim Zugriff auf dessen Value mittels HasValue überprüfen muß, ob überhaupt ein Wert vorliegt.

@erfahrener Neuling:
Mittels
ausblenden C#-Quelltext
1:
XmlDeclaration dec = doc.FirstChild as XmlDeclaration;					

solltest du an den Header herankommen, aber warum benötigst du diese Info?

Für diesen Beitrag haben gedankt: erfahrener Neuling
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Mi 09.03.16 17:00 
user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
@Christian: wir beide hatten nicht komplett recht ;-)
:zustimm:


user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
Bei Wertetypen ist also der ?.-Operator genauso unelegant, wie das Prüfen auf null, da man dann anschließend beim Zugriff auf dessen Value mittels HasValue überprüfen muß, ob überhaupt ein Wert vorliegt.

Oder man macht sowas:
ausblenden C#-Quelltext
1:
int x = a?.x ?? 42;					

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 09.03.16 17:06 
@Christian: Wow, super Lösung (nur daß man dann selber immer den Default-Wert hinschreiben muß)!

Ich plädiere für den ??.-Operator:
ausblenden C#-Quelltext
1:
int x = a??.x : 42;					

oder gleich mit integriertem Default-Wert:
ausblenden C#-Quelltext
1:
int x = a??.x;					

:D