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

Jetzt 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 7 Eingabe und Ausgabe
Pfeil 7.1 Namensräume der Ein- bzw. Ausgabe
Pfeil 7.2 Ausnahmebehandlung
Pfeil 7.3 Dateien und Verzeichnisse
Pfeil 7.3.1 Dateizugriff mit File
Pfeil 7.3.2 Dateizugriff mit FileInfo
Pfeil 7.3.3 Die Klassen Directory und DirectoryInfo
Pfeil 7.3.4 Dateizugriffe in Aktion
Pfeil 7.3.5 Pfade mit Path
Pfeil 7.3.6 Laufwerksinformation mit DriveInfo
Pfeil 7.3.7 SpecialDirectories
Pfeil 7.4 Datenflüsse in Streams
Pfeil 7.4.1 Die abstrakte Klasse Stream
Pfeil 7.4.2 Stream-Klassen im Überblick
Pfeil 7.4.3 Dateizugriff mit FileStream
Pfeil 7.5 Texte mit TextReader und TextWriter
Pfeil 7.5.1 Texte mit StreamWriter schreiben
Pfeil 7.5.2 Texte mit StreamReader lesen
Pfeil 7.5.3 Zeichenketten mit StringWriter und StringReader
Pfeil 7.6 Binärdaten mit BinaryReader und BinaryWriter
Pfeil 7.6.1 Schreiben mit BinaryWriter
Pfeil 7.6.2 Lesen mit BinaryReader
Pfeil 7.6.3 Binäre Datenströme auswerten
Pfeil 7.6.4 Komplexe binäre Daten
Pfeil 7.7 Serialisierung
Pfeil 7.7.1 Serialisierungsverfahren
Pfeil 7.7.2 Testklassen
Pfeil 7.7.3 Serialisierung mit BinaryFormatter
Pfeil 7.7.4 Serialisierung mit SoapFormatter
Pfeil 7.7.5 Serialisierung mit XmlSerializer


Rheinwerk Computing - Zum Seitenanfang

7.7 Serialisierung Zur nächsten ÜberschriftZur vorigen Überschrift

Die in Abschnitt 7.6.4, »Komplexe binäre Daten«, gezeigte Speicherung und Wiederherstellung ist eine Möglichkeit, Daten zur Wiederverwendung zu sichern. Viel einfacher ist es, sich auf die Möglichkeiten von .NET zu stützen. Der Prozess, Daten in einen Strom (zum Beispiel eine Datei) zu speichern, wird Serialisierung genannt.

Die Serialisierung kann ein im Hauptspeicher befindliches Objekt in ein bestimmtes Format konvertieren und in einen Strom schreiben. Außerdem kann das Objekt in seinem ursprünglichen Format rekonstruiert werden. Diese Prozesse laufen automatisch ab. Die gespeicherten Daten bestehen aus dem Namen der Anwendung, dem Namen der Klasse und den Objektdaten. Dadurch wird die spätere Rekonstruktion in einer exakten Kopie möglich.

Ein zu sichernder Objektzustand ist vollständig durch die Felder des Objekts beschrieben. Alle weiteren Informationen sind mit der Klasse verbunden und nicht Teil des Zustandes.


Rheinwerk Computing - Zum Seitenanfang

7.7.1 Serialisierungsverfahren Zur nächsten ÜberschriftZur vorigen Überschrift

Die .NET-Klassenbibliothek hat für die Formatierung der Objektdaten drei Klassen (siehe Tabelle 7.21). Sie bestimmen das Datenformat, das in den Strom geschrieben wird bzw. aus ihm gelesen wird.


Tabelle 7.21 .NET-Serialisierungsklassen

Klasse Übertragungsformat

BinaryFormatter

Binäres Format, das zirkuläre Referenzen unterstützt

SoapFormatter

SOAP-Format (Simple Object Access Protocol), das zirkuläre Referenzen unterstützt. System.Runtime.Serialization.Formatters.Soap.dll muss eingebunden werden.

XmlSerializer

XML-Format, das zirkuläre Referenzen nicht unterstützt. System.Xml.dll muss eingebunden werden.


Alle drei implementieren die Schnittstelle IFormatter. Kommen Sie mit keiner der drei Klassen zurecht, müssen Ihre eigenen Klassen diese Schnittstelle implementieren.


Public Interface IFormatter 
    Function Deserialize(serializationStream As Stream) As Object 
    Sub Serialize(serializationStream As Stream, graph As Object)

    Property Binder As SerializationBinder 
    Property Context As StreamingContext 
    Property SurrogateSelector As IsurrogateSelector 
End Interface

Die Speicherung von Objektdaten in einen Strom übernimmt Serialize. Das erste Argument spezifiziert den Strom, in den geschrieben wird; oft ist das ein FileStream. Das zu serialisierende Objekt wird im zweiten Parameter übergeben.

Die Methode Deserialize rekonstruiert ein Objekt. Das Argument spezifiziert den Strom, aus dem gelesen wird; oft ist das ein FileStream. Der Rückgabewert ist vom Typ Object und muss deshalb noch in den richtigen Typ konvertiert werden.


Rheinwerk Computing - Zum Seitenanfang

7.7.2 Testklassen Zur nächsten ÜberschriftZur vorigen Überschrift

Alle Objekte einer Klasse, die das Attribut Serializable hat, sind serialisierbar.

<Serializable()> Public Class ClassA ...

Wenn Sie versuchen, Objekte von Klassen zu serialisieren, die das Attribut nicht haben, wird die Ausnahme SerializationException ausgelöst. Alle Felder der Klasse ClassA, unabhängig davon, ob sie privat oder öffentlich deklariert sind, werden von der Serialisierung erfasst. Es gibt aber auch eine Einschränkung:


Lokale und klassengebundene Variablen nehmen an einem Serialisierungsprozess nicht teil.


Die meisten Beispiele zur Serialisierung verwenden eine Klasse ClassA mit einem privaten und einem öffentliches Feld, die beide über einen Konstruktor initialisiert werden.


'...\IO\Serialisierung\ClassA.vb

Namespace EA 
  <Serializable()> Public Class ClassA 
    Public intVar As Integer 
    Private strVar As String

    Public Sub New() 
    End Sub

    Public Sub New(ByVal x As Integer, ByVal str As String) 
      intVar = x 
      strVar = str 
    End Sub

    Property Name() As String 
      Get 
        Return strVar 
      End Get 
      Set(ByVal value As String) 
        strVar = value 
      End Set 
    End Property 
  End Class 
End Namespace

Einige Beispiele verwenden außerdem eine Klasse Person mit einem öffentlichen Feld:


'...\IO\Serialisierung\Binär.vb

Namespace EA 
  <Serializable()> Public Class Person 
    Public Name As String 
    Public Sub New(str As String) 
      Name = str 
    End Sub 
  End Class 
End Namespace

Bei der Serialisierung greift der Prozess den Inhalt von intVar und strName und speichert ihn entweder in einer Datei, im Netzwerk oder in einer Datenbank. Die Deserialisierung belegt diese beiden mit den gelesenen Werten.


Rheinwerk Computing - Zum Seitenanfang

7.7.3 Serialisierung mit BinaryFormatter Zur nächsten ÜberschriftZur vorigen Überschrift

Im folgenden Beispiel verwenden wir BinaryFormatter zur Formatierung der über einen Dateistrom geschickten Daten (zu ClassA siehe Abschnitt 7.7.2, »Testklassen«). Nach dessen Instanziierung erzeugen wir ein Testobjekt. Die Methode Serialize aus der Klasse BinaryFormatter speichert dieses Objekt in einem FileStream, der es wiederum in der angegebenen Datei speichert. Durch den Wert FileMode.Create ist sichergestellt, dass die Datei keine zusätzlichen Daten enthält. Danach lesen wir ein Objekt mit Deserialize aus einem FileStream, der auf dieselbe Datei zugreift, und konvertieren es in den richtigen Typ. Schließlich geben wir das gelesene Objekt aus. Um das Beispiel kurz zu halten, ist alles in einer Methode.


'...\IO\Serialisierung\Binär.vb

Option Strict On 
Imports System.IO 
Namespace EA 
  Module Binär 
    Sub Test() 
      Dim path As String = IO.Path.GetTempFileName() 
      Dim fs As FileStream

      ' Objekt und Formatierer erzeugen 
      Dim bf As New System.Runtime.Serialization.Formatters.Binary. _ 
        BinaryFormatter() 
      Dim obj As New ClassA(310, "Peter")

      ' speichern 
      fs = New FileStream(path, FileMode.Create) 
      bf.Serialize(fs, obj) 
      fs.Close()

      ' lesen 
      fs = New FileStream(path, FileMode.Open) 
      Dim obj2 As ClassA = CType(bf.Deserialize(fs), ClassA) 
      fs.Close()

      ' Ausgabe 
      Console.WriteLine("{{intVar={0}, Name={1}}}", obj2.intVar, obj2.Name) 
      File.Delete(path) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Ausgabe zeigt die Daten des mit New erzeugten Objekts; die Serialisierung hat geklappt.

{intVar=310, Name=Peter}

Serialisierung mehrerer Objekte

Der Serialisierungsprozess kann auch im Typ unterschiedliche Objekte erfassen. Für jedes Objekt erfolgt ein eigener Aufruf von Serialize bzw. Deserialize für denselben Strom. Die Reihenfolge der Objekte ist beim Schreiben und Lesen identisch. Das ist ein FIFO-Prinzip (first in – first out): Das zuerst serialisierte Objekt muss auch als Erstes wieder deserialisiert werden. Bitte beachten Sie, dass das Lesen über das Ende des Datenstroms hinaus eine Ausnahme zur Folge hat.

Anstatt jedes Objekt einzeln zu behandeln, packen wir die Objekte in eine Auflistung, die serialisierbar ist – im Beispiel ArrayList. Da sie die Objekte in Feldern speichert, werden sie von der Serialisierung erfasst, und durch den rekursiven Charakter der Serialisierung werden deren Felder ebenfalls serialisiert. Wie das folgende Beispiel zeigt, tritt dann einfach die Auflistung an die Stelle eines Einzelobjekts. Das bedeutet: Es gibt nur einen Aufruf Serialize und nur einen Aufruf Deserialize, für egal wie viele Objekte.

Das Beispiel verwendet die Klassen ClassA und Person des Abschnitts 7.7.2, »Testklassen«. Erst wird eine Liste mit verschiedenen Objekttypen serialisiert. Dann folgt die Deserialisierung mit anschließender Testausgabe.


'...\IO\Serialisierung\Gemischt.vb

Option Strict On 
Imports System.IO 
Imports System.Runtime.Serialization 
Imports System.Runtime.Serialization.Formatters.Binary 
Namespace EA 
  Module Gemischt 
    Sub Test() 
      Dim path As String = IO.Path.GetTempFileName() 
      Dim fs As FileStream

      ' Objekt und Formatierer erzeugen 
      Dim liste As New ArrayList() 
      liste.Add(New ClassA(2334, "Freddy")) 
      liste.Add(New Person("Microsoft")) 
      liste.Add(New ClassA(13, "Beate")) 
      liste.Add(New Person("Tollsoft")) 
      Dim bf As New BinaryFormatter()

      ' speichern 
      fs = New FileStream(path, FileMode.Create) 
      bf.Serialize(fs, liste) 
      fs.Close()

      ' lesen 
      fs = New FileStream(path, FileMode.Open) 
      Dim liste2 As ArrayList 
      Try 
        liste2 = CType(bf.Deserialize(fs), ArrayList) 
      Catch ex As SerializationException 
        Console.WriteLine("Serialisierung: {0}", ex.Message) : Return 
      Catch ex As IOException 
        Console.WriteLine("Lesefehler: {0}", ex.Message) : Return 
      Finally 
        fs.Close() 
      End Try

      ' Ausgabe 
      For Each o As Object In liste2 
        If TypeOf o Is ClassA Then 
          Dim c As ClassA = CType(o, ClassA) 
          Console.WriteLine("{{intVar={0}, Name={1}}}", c.intVar, c.Name) 
        Else 
          Dim p As Person = CType(o, Person) 
          Console.WriteLine("{{Name={0}}}", p.Name) 
        End If 
      Next

      File.Delete(path) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Ausgabe bestätigt die korrekte Serialisierung:

{intVar=2334, Name=Freddy} 
{Name=Microsoft} 
{intVar=13, Name=Beate} 
{Name=Tollsoft}

Nichtserialisierte Daten

Alle Felder mit dem Attribut NonSerialized sind explizit von der Serialisierung ausgenommen. Zum Beispiel sollten Felder mit Kennwörtern nicht gespeichert werden:

<Serializable()> Class Login 
  Public Name As String 
  <NonSerialized()> Private Kennwort As String 
  ... 
End Class

Serialisierung und Vererbung

Das Serializable-Attribut wird nicht vererbt. Wenn Sie eine serialisierbare Klasse ClassA entwickeln und daraus die Klasse ClassB ableiten, muss diese selbst dann das Attribut haben, wenn nur die aus ClassA geerbten Mitglieder serialisiert werden sollen. Ansonsten ist die Subklasse nicht serialisierbar. Weiterhin ist eine Kindklasse nur serialisierbar, wenn auch die Elternklasse serialisierbar ist.


Rheinwerk Computing - Zum Seitenanfang

7.7.4 Serialisierung mit SoapFormatter Zur nächsten ÜberschriftZur vorigen Überschrift

Die Serialisierung von Objektdaten mit SoapFormatter unterscheidet sich nicht von der mit BinaryFormatter. Allerdings muss zuerst eine weitere Bibliotheksdatei, wie in Tabelle 7.21, ».NET-Serialisierungsklassen« angegeben, unter Verweise eingetragen werden. Abbildung 7.5 zeigt eine typische Ausgabe, geöffnet im Internet Explorer.

Abbildung 7.5 Serialisierte Daten im SOAP-Format


Rheinwerk Computing - Zum Seitenanfang

7.7.5 Serialisierung mit XmlSerializer topZur vorigen Überschrift

Die Serialisierung mit der Klasse XmlSerializer aus dem Namensraum System.Xml.Serialization.XmlSerializer unterscheidet sich gravierend von den Klassen BinaryFormatter und SoapFormatter:

  • Die im XML-Format zu serialisierende Klasse muss als Public definiert sein.
  • Nur als Public deklarierte Instanzfelder werden serialisiert, klassengebundene sind ausgeschlossen.
  • Die zu serialisierende Klasse muss einen öffentlichen, parameterlosen Konstruktor haben. Dieser wird von XmlSerializer aufgerufen.
  • Die Steuerung der XML-Serialisierung erfolgt mit Attributen aus dem Namensraum System.Xml.Serialization.
  • Das Serializable-Attribut ist nicht zwingend vorgeschrieben.

Obwohl die XML-Serialisierung aufwändiger zu programmieren ist, hat sie einen großen Vorteil: XML ist ein offener Standard und deshalb plattformunabhängig. Die auf diese Weise serialisierten Daten lassen sich folglich von »beliebigen« Anwendungen verarbeiten.

Im folgenden Beispiel wird das Beispiel aus Abschnitt 7.7.3, »Serialisierung mit BinaryFormatter«, so umgeschrieben, dass statt des BinaryFormatter ein XmlSerializer verwendet wird. Die Serialisierungsklassen ClassA und Person zeigt Abschnitt 7.7.2, »Testklassen«.


'...\IO\Serialisierung\Xml.vb

Option Strict On 
Imports System.IO 
Imports System.Xml.Serialization 
Namespace EA 
  Module Xml 
    Sub Test() 
      Dim path As String = IO.Path.GetTempFileName() 
      Dim fs As FileStream

      ' Objekt und Formatierer erzeugen 
      Dim bf As New XmlSerializer(GetType(ClassA)) 
      Dim obj As New ClassA(310, "Peter")

      ' speichern 
      fs = New FileStream(path, FileMode.Create) 
      bf.Serialize(fs, obj) 
      fs.Close()

      ' lesen 
      fs = New FileStream(path, FileMode.Open) 
      Dim obj2 As ClassA = CType(bf.Deserialize(fs), ClassA) 
      fs.Close()

      ' Ausgabe 
      Console.WriteLine("{{intVar={0}, Name={1}}}", obj2.intVar, obj2.Name) 
      Console.WriteLine(File.ReadAllText(path))

      File.Delete(path) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Nur eine Zeile unterscheidet die binäre von der XML-Serialisierung:

Dim bf As New XmlSerializer(GetType(ClassA))

Der Inhalt der XML-Datei ist die zweite Ausgabe:

{intVar=310, Name=Peter}

<?xml version="1.0"?> 
<ClassA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
  <intVar>310</intVar> 
  <Name>Peter</Name> 
</ClassA>

XML-Serialisierung mit Attributen steuern

Die Auswahl der serialisierten Daten und deren Ausgabeformat lassen sich mit Attributen steuern, die im Namensraum System.Xml.Serialization definiert sind. Tabelle 7.22 gibt einen kleinen Überblick über die wichtigsten Attribute.


Tabelle 7.22 Attribute zur Steuerung der Ausgabe in einer XML-Datei

Attribut Beschreibung

XmlArray

Ein bestimmtes Klassenmitglied wird als Array serialisiert.

XmlArrayItem

Legt den XML-Bezeichner für den vom Array verwalteten Typ fest.

XmlAttribute

Die Eigenschaft wird als XML-Attribut statt als XML-Element serialisiert.

XmlElement

XML-Elementnamen, standardmäßig der Bezeichner des Feldes

XmlIgnore

Legt fest, dass die Eigenschaft nicht serialisiert werden soll.

XmlRoot

XML-Wurzelelement, standardmäßig der Name der serialisierten Klasse


Das folgende Beispiel verwendet einige der Attribute. Hier sehen Sie zuerst die Definition der zu serialisierenden Klasse: eine Teilnehmerliste mit einzelnen Teilnehmern.


'...\IO\Serialisierung\XmlAttribute.vb

Option Strict On 
Imports System.IO 
Imports System.Xml.Serialization 
Namespace EA

  <XmlRoot("PersonenListe")> Public Class Teilnehmerliste

    <XmlElement("Listenbezeichner")> Public Listenname As String

    <XmlArray("PersonenArray")> <XmlArrayItem("PersonObjekt")> _ 
    Public Personen As Teilnehmer()

    Public Sub New() 
    End Sub

    Public Sub New(ByVal name As String) 
      Listenname = name 
    End Sub 
  End Class

  Public Class Teilnehmer

    <XmlElement("Name")> Public Zuname As String

    <XmlElement("Wohnort")> Public Ort As String

    <XmlElement("Alter")> Public Lebensalter As Integer

    <XmlAttribute("PersID")> Public ID As String

    Public Sub New() 
    End Sub

    Public Sub New(zuname As String, ort As String, _ 
                   alter As Integer, id As String) 
      Me.Zuname = zuname 
      Me.Ort = ort 
      Me.Lebensalter = alter 
      Me.ID = id 
    End Sub 
  End Class 
  ...

End Namespace

Im Testcode erzeugen wir eine Teilnehmerliste mit zwei Teilnehmer-Einträgen, die wir wie üblich serialisieren und deserialisieren. Ansatt des XML-Dateiinhalts serialisieren wir das gerade deserialisierte Objekt in die Konsole.


'...\IO\Serialisierung\XmlAttribute.vb

Option Strict On 
Imports System.IO 
Imports System.Xml.Serialization 
Namespace EA 
  ...

  Module XmlAttribute 
    Sub Test() 
      Dim path As String = IO.Path.GetTempFileName() 
      Dim fs As FileStream

      ' Objekt und Formatierer erzeugen 
      Dim katalog As New Teilnehmerliste("Teilnehmerliste") 
      Dim personen(1) As Teilnehmer 
      personen(0) = New Teilnehmer("Peter", "Berlin", 45, "117") 
      personen(1) = New Teilnehmer() 
      personen(1).Zuname = "Franz-Josef" 
      personen(1).Ort = "Aschaffenburg" 
      katalog.Personen = personen

      Dim bf As New XmlSerializer(GetType(Teilnehmerliste))

      ' speichern 
      fs = New FileStream(path, FileMode.Create) 
      bf.Serialize(fs, katalog) 
      fs.Close()

      ' lesen 
      fs = New FileStream(path, FileMode.Open) 
      Dim katalog2 As Teilnehmerliste = _ 
        CType(bf.Deserialize(fs), Teilnehmerliste) 
      fs.Close()

      ' Ausgabe 
      bf.Serialize(Console.Out, katalog2) 
      'Console.WriteLine(File.ReadAllText(path)) 
      File.Delete(path) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Bis auf das encoding-Attribut der ersten Zeile zeigt die Ausgabe den Inhalt der XML-Datei:

<?xml version="1.0" encoding="IBM437"?> 
<PersonenListe xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
  <Listenbezeichner>Teilnehmerliste</Listenbezeichner> 
  <PersonenArray> 
    <PersonObjekt PersID="117"> 
      <Name>Peter</Name> 
      <Wohnort>Berlin</Wohnort> 
      <Alter>45</Alter> 
    </PersonObjekt> 
    <PersonObjekt> 
      <Name>Franz-Josef</Name> 
      <Wohnort>Aschaffenburg</Wohnort> 
      <Alter>0</Alter> 
    </PersonObjekt> 
  </PersonenArray> 
</PersonenListe>

Beachten Sie, wie die Verwendung der Attribute die Elementbezeichner in der XML-Ausgabe ändert.



Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Visual Basic 2008
Visual Basic 2008
Jetzt Buch bestellen


 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Rheinwerk-Shop: Visual Basic 2012






 Visual Basic 2012


Zum Rheinwerk-Shop: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Rheinwerk-Shop: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


Zum Rheinwerk-Shop: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Rheinwerk-Shop: Windows Presentation Foundation






 Windows Presentation
 Foundation


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
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

Cookie-Einstellungen ändern