Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
1 Einführung
2 Grundlagen der Sprachsyntax
3 Klassendesign
4 Weitere Datentypen
5 Multithreading
6 Collections und LINQ
7 Eingabe und Ausgabe
8 Anwendungen: Struktur und Installation
9 Code erstellen und debuggen
10 Einige Basisklassen
11 Windows-Anwendungen erstellen
12 Die wichtigsten Steuerelemente
13 Tastatur- und Mausereignisse
14 MDI-Anwendungen
15 Grafiken mit GDI+
16 Drucken
17 Entwickeln von Steuerelementen
18 Programmiertechniken
19 WPF – Grundlagen
20 Layoutcontainer
21 WPF-Steuerelemente
22 Konzepte von WPF
23 Datenbankverbindung mit ADO.NET
24 Datenbankabfragen mit ADO.NET
25 DataAdapter
26 Offline mit DataSet
27 Datenbanken aktualisieren
28 Stark typisierte DataSets
A Anhang: Einige Übersichten
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual Basic 2008 von Andreas Kuehnel, Stephan Leibbrandt
Das umfassende Handbuch
Buch: Visual Basic 2008

Visual Basic 2008
3., aktualisierte und erweiterte Auflage, geb., mit DVD
1.323 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1171-0
Pfeil 4 Weitere Datentypen
Pfeil 4.1 Module
Pfeil 4.2 Strukturen
Pfeil 4.2.1 Vor- und Nachteile von Referenz- und Werttypen
Pfeil 4.2.2 Initialisierung und Konstruktoren
Pfeil 4.2.3 Boxing
Pfeil 4.2.4 Innere Strukturen
Pfeil 4.2.5 ValueType
Pfeil 4.3 Enumerationen
Pfeil 4.3.1 Datentyp
Pfeil 4.3.2 System.Enum
Pfeil 4.4 Generisches
Pfeil 4.4.1 Einschränkungen
Pfeil 4.4.2 Innere generische Typen
Pfeil 4.4.3 Vererbung und Überladung
Pfeil 4.4.4 Sichtbarkeit
Pfeil 4.4.5 Bindung
Pfeil 4.4.6 Rekursive Typen
Pfeil 4.4.7 Generische Typen in .NET
Pfeil 4.5 Werttypen mit dem Wert Nothing
Pfeil 4.5.1 Typumwandlungen
Pfeil 4.5.2 Logische Operatoren
Pfeil 4.5.3 Boxing
Pfeil 4.6 Anonyme Klassen
Pfeil 4.6.1 Automatische Namen
Pfeil 4.6.2 Schlüssel und Equals
Pfeil 4.6.3 Innere anonyme Klassen
Pfeil 4.6.4 Generierter Code
Pfeil 4.7 Spezielle Typen
Pfeil 4.8 Attribute
Pfeil 4.8.1 Beispiel: Bedingte Kompilierung
Pfeil 4.8.2 Codeerzeugung: DesignerGenerated
Pfeil 4.8.3 Standardinstanzen: MyGroupCollectionAttribute
Pfeil 4.8.4 Klassenerweiterungen: Extension
Pfeil 4.8.5 Attribute abfragen
Pfeil 4.8.6 Benutzerdefinierte Attribute


Rheinwerk Computing - Zum Seitenanfang

4.2 Strukturen Zur nächsten ÜberschriftZur vorigen Überschrift

Alle Objekte, die als Datentyp eine Klasse haben, nutzen eine Referenz auf das Objekt für den Zugriff auf das Objekt. Bei einer Weitergabe des Objekts wird nur die Referenz und nicht das Objekt selbst weitergegeben. Demgegenüber haben Sie bei Werttypen das Objekt selbst »in der Hand«. Damit nun das Originalobjekt nicht »verschwindet«, wird bei einer Weitergabe jedes Mal eine Kopie angefertigt. Dieser Unterschied zwischen Referenz- und Werttypen ist in Abschnitt 3.1.9, »Datentypen«, näher beschrieben. Mit den Strukturen haben Sie zum ersten Mal die Möglichkeit, selbst Werttypen zu definieren. Sie haben folgende Syntax (optionale Teile stehen in eckigen Klammern, kursiv gesetzte Teile müssen Sie Ihren Erfordernissen anpassen, zur Typen-Spezifikation siehe Abschnitt 4.4, »Generisches«):


[<Modifikatoren>] Structure Struktur[Typen] 
  [Implements <Schnittstellen>]

  Variable oder Ereignis 
  ... 
End Structure

Eine Struktur ist bis auf das Wort Structure statt Class identisch mit einer Klasse (inklusive der Aufteilbarkeit mit Partial), außer dass sie

  • nie mit Inherits die Elternklasse angibt, sondern implizit von ValueType erbt (konsequenterweise ist die Verwendung von MyBase verboten),
  • nie beerbt werden kann, sondern immer implizit NotInheritable ist,
  • als Modifikatoren nur Partial, Public und Friend erlaubt – sowie Shadows, Private und Protected für Strukturen als Teil anderer Datentypen,
  • mindestens eine Variable oder ein Ereignis deklarieren muss,
  • nie benutzerdefinierte parameterlose Objektkonstruktoren hat (ein mit Shared deklarierter Klassenkonstruktor ist erlaubt),
  • den parameterlosen Konstruktor nicht durch benutzerdefinierte Konstruktoren verliert,
  • nie objektgebundene Strukturvariablen innerhalb der Deklaration initialisiert (mit Shared deklarierte klassengebundene Variablen dürfen initialisiert werden) und
  • für Strukturvariablen WithEvents nicht spezifizieren darf und auch nicht als Datentyp für eine beliebige Variable benutzt werden darf, die WithEvents spezifiziert.

Die folgenden Codefragmente sind daher alle fehlerhaft:

'Compilerfehler: Struktur enthält weder eine Variable noch ein Ereignis!! 
Structure Struktur 
End Structure

'Compilerfehler: Angabe einer Elternklasse!! 
Structure Struktur Inherits ValueType 
  Dim var As Single 
End Structure

'Compilerfehler Struktur: Strukturen sind NotInheritable!! 
Structure Basis : Dim var As Single : End Structure 
Structure Struktur : Inherits Basis : Dim var As Single : End Structure 
Class Klasse : Inherits Basis : End Class

Structure Struktur 
  Dim var As Single = 0    'Compilerfehler: Initialisierung!! 
  Sub New()                'Compilerfehler: parameterlos ohne Shared!! 
  End Sub 
  WithEvents x As String   'Compilerfehler: WithEvents!! 
End Structure

Als erstes Beispiel schauen wir uns die Definition einer Person an. Es fällt auf, dass eine Objekterzeugung mit New fehlt. Da eine Struktur ein Werttyp ist, werden ihre Daten direkt in dem Block gespeichert, in dem die Strukturvariable deklariert wird, und nicht auf dem blockunabhängigen Heap, der alle Referenztypen speichert. Die Struktur enthält auch eine Methode Info(), um darauf aufmerksam zu machen, dass Strukturen nicht auf Variablen und Ereignisse beschränkt sind. Der Zugriff in Test() unterscheidet sich formal nicht von dem, den Objekte einer Klasse nutzen.


'...\Datentypen\Strukturen\Prinzip.vb

Option Strict On 
Namespace Datentypen

  Structure Person 
    Friend Name As String 
    Sub Info() 
      Console.WriteLine("Name: {0}", Name) 
    End Sub 
  End Structure

  Module Prinzip 
    Sub Test() 
      Dim p As Person                        'kein New!! 
      p.Info() 
      p.Name = "Winston Smith" 
      p.Info() 
      Console.ReadLine() 
    End Sub 
  End Module

End Namespace

Die erste Ausgabe zeigt, dass der durch die Deklaration implizit aufgerufene parameterlose Konstruktor keinen Einfluss auf die Strukturvariable hat. Sie ist mit einem Leerstring "" belegt. Andere Datentypen erhalten analog eine datentypspezifische »Null« (siehe Abschnitt 2.5.6, »Initialisierung von Variablen«). Nach der Zuweisung eines Namens wird dieser in der zweiten Ausgabe verwendet.

Name: 
Name: Winston Smith

Hinweis
Ganz neue Werttypen analog zu Strukturen können nicht von Ihnen geschaffen werden.



Rheinwerk Computing - Zum Seitenanfang

4.2.1 Vor- und Nachteile von Referenz- und Werttypen Zur nächsten ÜberschriftZur vorigen Überschrift

Klassen und Strukturen unterscheiden sich im Wesentlichen darin, wo die Daten eines Objekts gespeichert werden. Erstere sind Referenztypen, und Variablen dieses Typs halten nur einen Verweis auf die eigentlichen Daten, während bei Letzteren die Daten direkt in der Objektvariablen gespeichert sind. Wird eine Variable an eine Methode weitergegeben oder einer anderen Variablen zugewiesen, erfolgt bei einem Referenztyp der Zugriff immer auf die Originaldaten, während bei Werttypen mit einer Kopie der Daten gearbeitet wird. Zusammengefasst hat ein Werttyp folgende Charakteristika:

  • Vorteile: Originaldaten bleiben erhalten, Objektkopien erfolgen implizit durch Weitergabe.
  • Nachteile: Originaldaten können nicht geändert werden, Kopien verbrauchen Ressourcen.

Um den Kopiermechanismus zu veranschaulichen, zeigt das nächste Codefragment die Veränderung einer Struktur namens Glasscheibe in einer Methode Verkauf(), die die Struktur als Parameter entgegennimmt und die Mitgliedsvariable Preis ändert. Die Änderung der Struktur selbst ist erforderlich, da die Methode Info() die Struktur selbst als einzige Informationsquelle nutzt. Ob das ein glückliches Design darstellt, sei dahingestellt, hier kommt es nur auf den Mechanismus des Kopierens an.


'...\Datentypen\Strukturen\Kopien.vb

Option Strict On 
Namespace Datentypen

  Structure Glasscheibe 
    Public Preis As Double 
    Public Farbe As String 
    Sub Info() 
      Console.WriteLine("{0}es Glas kostet {1}", Farbe, Preis) 
    End Sub 
  End Structure

  Module Kopien 
    Sub Verkauf(ByVal glas As Glasscheibe) 
      glas.Preis *= 1.19 
      glas.Info() 
    End Sub

    Sub Test() 
      Dim rot As Glasscheibe : rot.Farbe = "Rot" : rot.Preis = 172 
      Verkauf(rot) : Verkauf(rot) 
      Dim blau As Glasscheibe = rot : blau.Farbe = "Blau" : blau.Preis = 124 
      Verkauf(rot) : Verkauf(blau) 
      Console.ReadLine() 
    End Sub 
  End Module

End Namespace

Die ersten beiden Ausgaben zeigen, dass die Änderung der Strukturvariablen in der Methode Verkauf() sich trotz des zweimaligen Aufrufs nicht auf das Original auswirkt und daher immer der korrekte Preis ausgegeben wird (und nicht durch jeden Verkauf erhöht wird). Auch bei der Zuweisung der Variablen blau wird keine zweite Referenz auf dieselben Daten erzeugt, sondern die Daten werden kopiert, wie die gegenüber den ersten Zeilen unveränderte Ausgabe in der dritten Zeile zeigt:

Rotes Glas kostet 204.68 
Rotes Glas kostet 204.68 
Rotes Glas kostet 204.68 
Blaues Glas kostet 147.56

Hinweis
Bei Werttypen gibt es nie zwei Referenzen auf dieselben Daten.



Rheinwerk Computing - Zum Seitenanfang

4.2.2 Initialisierung und Konstruktoren Zur nächsten ÜberschriftZur vorigen Überschrift

Strukturen haben natürlich auch die Möglichkeit, Konstruktoren zu deren Initialisierung zu definieren. Anders als bei Klassen muss jeder selbst definierte Konstruktor Parameter besitzen, wobei der parameterlose Standardkonstruktor in jeder Situation zur Verfügung gestellt wird (und gar nicht selbst definiert werden kann). Damit geht einher, dass es unmöglich ist, durch private Konstruktoren die Instanziierung einer Struktur komplett zu kontrollieren oder gar zu verhindern. Im Kontext automatisch erstellter Kopien bei der Weitergabe oder Zuweisung ist eine solche Beschränkung sinnvoll. Da die Initialisierung von Variablen in einer Struktur während der Deklaration nicht erlaubt ist, sind benutzerdefinierte Konstruktoren selbst dann sinnvoll, wenn die Struktur mit den immer gleichen Werten ungleich »Null« starten soll. In einem solchen Fall müssen Sie halt mit einem Dummy-Parameter im Konstruktor arbeiten, da Ihnen der parameterlose Konstruktor ja verwehrt ist.

Das nächste Codefragment definiert eine Struktur zur Speicherung eines Punktes mit zwei benutzerdefinierten Konstruktoren, wobei der zweite zufällige Werte für x und y nimmt und die z-Koordinate nicht initialisiert, sondern bei 0 belässt (im Gegensatz zu C# müssen in Visual Basic nicht alle verwendeten Strukturvariablen explizit initialisiert werden). Da die Koordinatenvariablen mit Private deklariert sind, kann ein einmal erzeugter Punkt nicht mehr geändert werden. Die überschriebene Methode ToString() wird »lesbare« Ausgaben produzieren.


'...\Datentypen\Strukturen\Konstruktoren.vb

Option Strict On 
Namespace Datentypen 
  Structure Punkt

    Private x, y, z As Double

    Sub New(ByVal x As Double, ByVal y As Double, _ 
            Optional ByVal z As Double = z0)                'z0 siehe unten 
      Me.x = x : Me.y = y : Me.z = z 
    End Sub

    Sub New(ByVal start As Integer) 
      Dim rand As Random = New Random(start) 
      x = rand.NextDouble() : y = rand.NextDouble() 
    End Sub

    Public Overrides Function ToString() As String 
      Return "{" & x.ToString("0.##") & "," & y.ToString("0.##") & _ 
                                        "," & z.ToString("0.##") & "}" 
    End Function

  End Structure 
  ... 
End Namespace

Zum Test werden Tetraederpunkte mit zwei und drei Koordinaten erzeugt und in der Methode Ausgabe() protokolliert, die ein Array von Punkten erwartet. Analog werden Dreieckspunkte mit einem Parameter generiert und ausgegeben. Schließlich wird bei der Variablen null ganz auf Parameter verzichtet.


'...\Datentypen\Strukturen\Konstruktoren.vb

Option Strict On 
Namespace Datentypen 
  ... 
  Module Konstruktoren

    Public Const z0 As Double = –0.20412414523193151   '-1/(2*Math.Sqrt(6))

    Sub Ausgabe(ByVal was As String, ByVal p As Punkt()) 
      Console.Write("{0}: |", was) 
      For Each pt As Punkt In p : Console.Write("{0}|", pt) : Next 
      Console.WriteLine() 
    End Sub

    Sub Test() 
      Dim x As Double = 1 / (2 * Math.Sqrt(3)) 
      Dim tetraeder As Punkt() = {New Punkt(0, 0, z0 + Math.Sqrt(2 / 3)), _ 
          New Punkt(-x, –1 / 2), New Punkt(-x, 1 / 2), New Punkt(2 * x, 0)} 
      Ausgabe("Tetraeder", tetraeder)

      Dim dreieck As Punkt() = {New Punkt(0), New Punkt(1), New Punkt(2)} 
      Ausgabe("Dreieck", dreieck)

      Dim null As Punkt 
      Console.WriteLine("Nullpunkt: {0}", null) 
      null = New Punkt() 
      Console.WriteLine("Nullpunkt: {0}", null) 
      Console.ReadLine()

    End Sub 
  End Module 
End Namespace

Die erste Ausgabe bestätigt die Verwendung des dreiparametrigen Konstruktors unter Verwendung des optionalen z-Wertes. Das Dreieck verwendet den einparametrigen Konstruktor mit zufälligen Koordinaten. Die letzten beiden Ausgaben dokumentieren den impliziten und den expliziten Einsatz des immer vorhandenen parameterlosen Konstruktors.

Tetraeder: |{0,0,0.61}|{-0.29,-0.5,-0.2}|{-0.29,0.5,-0.2}|{0.58,0,-0.2}| 
Dreieck: |{0.73,0.82,0}|{0.25,0.11,0}|{0.77,0.4,0}| 
Nullpunkt: {0,0,0} 
Nullpunkt: {0,0,0}

Rheinwerk Computing - Zum Seitenanfang

4.2.3 Boxing Zur nächsten ÜberschriftZur vorigen Überschrift

Jedes Objekt ist (unter anderem) vom Typ Object und – beim Einsatz einer Implements-Klausel – vom entsprechenden Schnittstellentyp. Da beide Referenztypen sind, kann die Situation auftreten, dass eine Referenz auf eine Struktur gebraucht wird. Damit die Handhabung einfach bleibt, wird die hierfür notwendige Funktionalität, inklusive des Kopierens, vom Compiler erzeugt bzw. von der Laufzeitumgebung bereitgestellt. Der Mechanismus wird Boxing genannt, da ein Werttyp in einen Referenztyp verpackt wird. Der umgekehrte Weg heißt Unboxing.

Das nächste Codefragment prüft, ob durch das Boxing und Unboxing durch CType eine Kopie der Struktur erstellt wird. Dazu wird durch Zuweisung an eine Variable vom Typ Object eine Referenz auf eine Struktur erzeugt. Danach wird die Struktur geändert, und es werden sowohl die Struktur als auch die Referenz ausgegeben. Analog wird die Referenz an die Strukturvariable zugewiesen, Letztere wird geändert, und beide werden ausgegeben. Dabei muss das Auslesen der Referenz vom Typ Object über Reflection erfolgen, da sie sonst nur über eine Typumwandlung auszulesen wäre und es ja gerade darum geht, ob eine solche Umwandlung eine Kopie erzeugt.


'...\Datentypen\Strukturen\Boxing.vb

Option Strict On 
Namespace Datentypen

  Structure Schauspieler 
    Public Name As String 
    Sub New(ByVal name As String) 
      Me.Name = name 
    End Sub 
  End Structure

  Module Boxing 
    Sub Test()

      Dim person As New Schauspieler("Marion Robert Morrison") 
      Dim ref As Object = person 
      Dim name As Reflection.FieldInfo = ref.GetType().GetField("Name")

      person.Name = "Marion Michael Morrison" 
      Console.WriteLine("Schauspieler {0}", person.Name) 
      Console.WriteLine("Referenz {0}", name.GetValue(ref))

      person = CType(ref, Schauspieler) 
      person.Name = "The Duke" 
      Console.WriteLine("Schauspieler {0}", person.Name) 
      Console.WriteLine("Referenz {0}", name.GetValue(ref))

      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Der Vergleich der ersten beiden und der letzten beiden Ausgaben zeigt jeweils, dass sowohl beim Boxing als auch beim Unboxing das Original erhalten bleibt und eine Kopie der Struktur erstellt wird.

Schauspieler Marion Michael Morrison 
Referenz Marion Robert Morrison 
Schauspieler The Duke 
Referenz Marion Robert Morrison

Hinweis
Wie jede andere Art der Konvertierung greifen die Boxing-Mechanismen wenn nötig auf implizite Konvertierungen zurück.



Hinweis
Wenn eine Struktur eine Schnittstelle implementiert und als Letztere angesprochen wird, dann findet ein Boxing statt, da jede Schnittstelle ein Referenztyp ist.



Rheinwerk Computing - Zum Seitenanfang

4.2.4 Innere Strukturen Zur nächsten ÜberschriftZur vorigen Überschrift

Wie Klassen können Strukturen sowohl andere Datentypen enthalten als auch Teil anderer Datentypen sein. Deklaration und Zugriff funktionieren wie bei Klassen (siehe Abschnitt 3.8, »Innere Klassen«). Eine Besonderheit gibt es aber: Da Strukturen Werttypen sind, wird bei der Weitergabe oder Zuweisung eine Kopie der Struktur erstellt. Wie wird da mit geschachtelten Datentypen verfahren?

Im folgenden Codefragment enthält die Struktur Regal eine Referenzvariable box, deren Klasse die Variable Buchnummer zur Identifikation enthält. In der Methode Test() wird die Struktur instanziiert und danach zur Erstellung einer automatischen Kopie einer anderen Variablen zugewiesen. Schließlich wird die Buchnummer in der ersten Struktur abgeändert, und beide Strukturen werden ausgegeben.


'...\Datentypen\Strukturen\FlacheKopie.vb

Option Strict On 
Namespace Datentypen

  Class Schachtel 
    Public Buchnummer As Integer 
    Sub New(ByVal nummer As Integer) 
      Buchnummer = nummer 
    End Sub 
  End Class

  Structure Regal 
    Public box As Schachtel 
    Sub New(ByVal nummer As Integer) 
      box = New Schachtel(nummer) 
    End Sub 
  End Structure

  Module FlacheKopie 
    Sub Test()

      Dim Wohnzimmer As New Regal(27) 
      Dim Schlafzimmer As Regal = Wohnzimmer 
      Wohnzimmer.box.Buchnummer = 12

      Console.WriteLine("Wohnzimmer {0}", Wohnzimmer.box.Buchnummer) 
      Console.WriteLine("Schlafzimmer {0}", Schlafzimmer.box.Buchnummer)

      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Ausgabe zeigt, dass die Änderung der Nummer in der einen Struktur auch die andere Struktur betrifft. Das, worauf die Variable box verweist, ist also nicht kopiert worden.

Wohnzimmer 12 
Schlafzimmer 12

Damit lässt sich festhalten:


Kopien von Werttypen sind flach, das heißt, die Daten von Referenzen werden nicht kopiert, sondern nur die Referenz selbst.



Rheinwerk Computing - Zum Seitenanfang

4.2.5 ValueType topZur vorigen Überschrift

Durch die Deklaration einer Struktur wird implizit eine gleichnamige Klasse identischen Inhalts erzeugt, die auf der Klasse ValueType basiert. Sie dürfen diese Vererbungsbeziehung nicht herstellen, dies bleibt dem Compiler vorbehalten. Die Deklaration

Structure Struktur 
  Public Variable As Single 
End Structure

entspricht folgender Situation (fiktiv in Bezug auf die Darstellung der Struktur als Klasse):

Public NotInheritable Class Struktur Inherits ValueType 
  Public Variable As Single 
End Struktur

Public MustInherit Class ValueType Inherits Object 
  Public Overrides Function GetHashCode() As Integer 
  Public Overrides Function Equals(ByVal obj As Object) As Boolean 
  Public Overrides Function ToString() As String 
  Private Shared Function CanCompareBits(ByVal obj As Object) As Boolean 
  Private Shared Function _ 
    FastEqualsCheck(ByVal a As Object, ByVal b As Object) As Boolean 
End Class

Daraus können Sie erkennen, dass die Elternklasse aller Werttypen selbst ein Referenztyp ist (so merkwürdig das auch scheinen mag).


Hinweis
Neben Strukturen zählen noch die Primitiven (außer Strings) und Enumerationen zu den Werttypen.




Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  Zum Katalog
Zum Katalog: Visual Basic 2008
Visual Basic 2008
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Visual Basic 2012






 Visual Basic 2012


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


Zum Katalog: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Katalog: Windows Presentation Foundation






 Windows Presentation
 Foundation


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de