<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Software Archive -</title>
	<atom:link href="https://gernardt.net/category/informatik/software/feed/" rel="self" type="application/rss+xml" />
	<link>https://gernardt.net/category/informatik/software/</link>
	<description></description>
	<lastBuildDate>Tue, 03 Mar 2026 19:15:33 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://gernardt.net/wp-content/uploads/2026/03/favicon-1-150x150.png</url>
	<title>Software Archive -</title>
	<link>https://gernardt.net/category/informatik/software/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Kleiner QR Code Generator</title>
		<link>https://gernardt.net/kleiner-qr-code-generator/</link>
					<comments>https://gernardt.net/kleiner-qr-code-generator/#respond</comments>
		
		<dc:creator><![CDATA[Stephan Gernardt]]></dc:creator>
		<pubDate>Sun, 15 Feb 2026 22:33:40 +0000</pubDate>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[generaor]]></category>
		<category><![CDATA[kostenlos]]></category>
		<category><![CDATA[lizenzkostenfrei]]></category>
		<category><![CDATA[qr code]]></category>
		<category><![CDATA[qrcode]]></category>
		<guid isPermaLink="false">https://gernardt.net/?p=933</guid>

					<description><![CDATA[<p>Ich habe einen Freund, der auf der Suche nach einem QR‑Code®‑Generator war geholfen, da er nur kostenpflichtige online QR Code [&#8230;]</p>
<p>Der Beitrag <a href="https://gernardt.net/kleiner-qr-code-generator/">Kleiner QR Code Generator</a> erschien zuerst auf <a href="https://gernardt.net"></a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Ich habe einen Freund, der auf der Suche nach einem QR‑Code®‑Generator war geholfen, da er nur kostenpflichtige online QR Code Generatoren gefunden hat.</p>



<p>Viele Online‑Dienste bieten zwar „kostenfreie“ QR‑Codes® an, leiten jedoch Weblinks über ihre eigenen Server um. Nach einer gewissen Anzahl von Scans oder nach einer Testphase verlangen einige dieser Anbieter plötzlich monatliche Gebühren oder ein kostenpflichtiges Upgrade.</p>



<p>Um genau diese Abhängigkeiten und versteckten Kosten zu vermeiden, wurde dieses Programm entwickelt. Es ermöglicht das Erstellen von QR‑Codes® direkt auf dem eigenen Gerät – ohne Umleitungen, ohne Tracking und ohne Gebühren.</p>



<p>Die Verwendung von QR‑Codes ist lizenz‑ und kostenfrei.<br>Der Begriff <strong>„QR Code®“</strong> ist jedoch ein eingetragenes Warenzeichen der <a href="https://www.denso-wave.com/en/" type="link" id="https://www.denso-wave.com/en/" target="_blank" rel="noreferrer noopener nofollow"><strong>Denso Wave Incorporated</strong> (externer Link)</a>.<br>Dies gilt unter anderem in Japan, den Vereinigten Staaten von Amerika, Australien und in Europa.</p>



<p>Die Technologie selbst ist frei nutzbar, aber die Markenbezeichnung „QR Code®“ unterliegt dem Markenschutz des Unternehmens.</p>



<p>Das Programm ist bewusst minimalistisch gehalten und lässt sich sehr einfach bedienen.<br></p>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-6c531013 wp-block-group-is-layout-flex">
<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="801" height="480" src="https://gernardt.net/wp-content/uploads/2026/02/000qrcodegenerator.png" alt="Bild des QRCode Generator" class="wp-image-938" srcset="https://gernardt.net/wp-content/uploads/2026/02/000qrcodegenerator.png 801w, https://gernardt.net/wp-content/uploads/2026/02/000qrcodegenerator-300x180.png 300w, https://gernardt.net/wp-content/uploads/2026/02/000qrcodegenerator-768x460.png 768w" sizes="(max-width: 801px) 100vw, 801px" /><figcaption class="wp-element-caption">QR Code Generator</figcaption></figure>



<ol class="wp-block-list">
<li>Text bei QRCode Text eingeben</li>



<li>Dateiname bei &#8222;Speichern als&#8220; angeben, zur Auswahl des Pfades kann der Button mit den 3 Punkten gewählt werden.</li>



<li>Wenn gewünscht kann bei Farbe des QRCode, die Farbe des Codes ausgewählt werden.</li>



<li>Wenn gewünscht kann bei Farbe Hintergrund des QRCode, die Hintergrundfarbe des Codes ausgewählt werden.</li>



<li>Ist ein Logo gewünscht, kann ein Logo (oder Bild) ausgewählt werden.</li>



<li>Zuletzt kann die größe des Logos angegeben werden.</li>



<li>Nun auf Generieren klicken um den Code zu generieren.</li>
</ol>
</div>



<h2 class="wp-block-heading">Hinweise zur Größe des Logos</h2>



<p>Die Logo‑Größe ist standardmäßig auf 20 % der QR‑Code‑Fläche eingestellt.<br>In der aktuellen Implementierung arbeitet der QR‑Code mit einer Fehlerkorrekturstufe von 25 % (ECC‑Level Q).</p>



<p>Da die Fehlerkorrektur maximal etwa 25 % der Modulfläche kompensieren kann, darf das Logo technisch bedingt nicht größer sein als dieser Anteil. Wird eine größere Fläche überdeckt, können die für die Decodierung erforderlichen Module nicht mehr vollständig rekonstruiert werden, was die Lesbarkeit des QR‑Codes beeinträchtigt oder vollständig verhindert.</p>
<p>Der Beitrag <a href="https://gernardt.net/kleiner-qr-code-generator/">Kleiner QR Code Generator</a> erschien zuerst auf <a href="https://gernardt.net"></a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gernardt.net/kleiner-qr-code-generator/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Event (Grundlagen)</title>
		<link>https://gernardt.net/event-grundlagen/</link>
					<comments>https://gernardt.net/event-grundlagen/#respond</comments>
		
		<dc:creator><![CDATA[Stephan Gernardt]]></dc:creator>
		<pubDate>Wed, 11 Jun 2025 21:38:35 +0000</pubDate>
				<category><![CDATA[Beispielcodes & Erklärungen]]></category>
		<guid isPermaLink="false">https://gernardt.net/?p=790</guid>

					<description><![CDATA[<p>Im Beitrag Delegates Grundlagen wie einzelne oder mehrere Methoden gekapselt werden können, also flexible Methodenreferenzen verwalten können.Diese Technik bildet auch [&#8230;]</p>
<p>Der Beitrag <a href="https://gernardt.net/event-grundlagen/">Event (Grundlagen)</a> erschien zuerst auf <a href="https://gernardt.net"></a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Im Beitrag <a href="https://gernardt.net/788/" data-type="post" data-id="788">Delegates Grundlagen</a> wie einzelne oder mehrere Methoden gekapselt werden können, also flexible Methodenreferenzen verwalten können.<br>Diese Technik bildet auch die Grundlage für Events in C#. Während Delegates für den Allgemeinen Methoden Aufruf verwendet werden können, bieten Events die Möglichkeit auf Benachrichtigungen zu reagieren.</p>



<h2 class="wp-block-heading">Erstes Beispielprojekt zu Events</h2>



<p>Wir erstellen eine Klasse <em>Rechner</em>, diese besitz eine Methode Namens <em>Addiere</em>. Diese Methode soll 2 Zahlen miteinander addieren und das Ergebnis über einem Event veröffentlichen.</p>



<pre class="wp-block-code"><code>class Rechner {
    // Delegat welches vom Event verwendet wird um den Erfolg einer Rechnung zu Signalisieren    
    public delegate void ErgebnisRechnungsErfolgHandler(int ergebnis);
    // Event 
    public event ErgebnisRechnungsErfolgHandler ErgebnisMelden;
    /// &lt;summary>
    /// Addieren 
    /// &lt;/summary>
    /// &lt;param name="a">Zahl 1&lt;/param>
    /// &lt;param name="b">Zahl 2&lt;/param>
    /// &lt;remarks>
    /// Statt einen Rückgabewert wird ein Event ausgelößt wenn die Berechnung beendet ist
    /// &lt;/remarks>
    public void Addiere(int a, int b)
    {
        int result = a + b;

        // Event auslösen (kurze schreibweise)
        ErgebnisMelden?.Invoke(result);
        // Event auslösen (lange schreibweise)
        //if (!(ErgebnisMelden == null))
        //    ErgebnisMelden(result);
    }
}</code></pre>



<p>Was geschieht in der Klasse Rechner:<br>Zunächst wird ein Delegate deklariert: &#8222;<em>public delegate void ErgebnisRechnungsErfolgHandler(int ergebnis);</em>&#8222;. Um die Grundlagen von Delegates zu vertiefen, kann dies an im Beitrag <a href="https://gernardt.net/788/" data-type="post" data-id="788">Delegates (Grundlagen) </a>nachgelesen werden.<br>Anschließend wird das Delegate mit einem Event verbunden, das von der Klasse aufgerufen wird: &#8222;<em>public event ErgebnisRechnungsErfolgHandler ErgebnisMelden;</em>&#8222;. Das Schlüsselwort <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-ast-global-color-0-color">event</mark> stellt sicher, dass sich externe Teilnehmer nur an diesem Delegate anmelden (+=) oder abmelden (-=) können, während die Kontrolle bei der Klasse Rechner als Auslöser bleibt.<br>Um das Event auszulösen kann einfach das Event, wie auch jede andere Methode aufgerufen werden mit &#8222;ErgebnisMelden(result)&#8220;. <br>Aber ACHTUNG, wenn das Event nicht implementiert worden ist, tritt hier ein Fehler auf da der &#8222;Zeiger&#8220; des Events ins nichts zeigt. Aus diesem Grund habe ich hier im Code 2 Möglichkeiten aufgezeigt welche ein Absturz des Programmes verhindern.<br>Die erste Möglichkeit und kurze Möglichkeit ist &#8222;ErgebnisMelden?.Invoke(result);&#8220;. Wenn das Event Ereignismelden abonniert ist, dann wird das Event ausgeführt, sollte es nicht abonniert sein, wird das Event nicht ausgelöst.<br>Die zweite Möglichkeit ist für Beginner mit der Thematik einfacher verständlich.</p>



<pre class="wp-block-code"><code>if (!(ErgebnisMelden == null))
    ErgebnisMelden(result);</code></pre>



<p>Es wird erst geprüft ob das Event ErgebnisMelden abonniert ist. Wenn es abonniert ist, wird es ausgeführt.</p>



<p>Wir haben nun die Klasse die Arbeitet, nun möchten wir natürlich auch das Programm erstellen welches die Methoden der Klasse anwendet.</p>



<pre class="wp-block-code"><code>static void Main(string&#91;] args){
    Rechner rechne = new Rechner();                 // Rechner instanziieren
    rechne.ErgebnisMelden += Rechne_ErgebnisMelden; // Event abonnieren
    rechne.Addiere(1, 2);
    Console.WriteLine("Taste zum beenden.");
    Console.ReadKey();
}
private static void Rechne_ErgebnisMelden(int ergebnis){
    Console.WriteLine($"Ergebnis der Berechnung: {ergebnis}");
}</code></pre>



<p>Was geschieht im Code?<br>Nach der Instanziierung der Klasse wird das in der Klasse definierte Event ErgebnisMelden mittels += abonniert: &#8222;<em><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-ast-global-color-8-color">rech.ErgebnisMelden</mark> += <mark style="background-color:rgba(0, 0, 0, 0);color:#00d084" class="has-inline-color">Rechne_ErgebnisMelden</mark>;</em>&#8222;. Das <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-ast-global-color-8-color">abonnierte Event</mark> verweist anschließend auf <mark style="background-color:rgba(0, 0, 0, 0);color:#00d084" class="has-inline-color">die Methode, die mit dem Ergebnis weiterarbeitet</mark>.<br></p>



<p>Dieses kleine Beispiel zeigt wie Events funktionieren. <br>Im Beispielcode Download zu diesem Artikel ist ein 2tes (Windows Forms Projekt) enthalten. In diesem Windows Forms Projekt ist eine Klasse welche eine längere Aufgabe (Strings addieren) übernimmt und mittels Event zum einen den Status der Aufgabe (z.B. für einen Fortschrittsbalken) übergibt und das Ende der Aktion signalisiert. Als lange Aufgabe habe ich das Beispiel aus dem Eintrag <a href="https://gernardt.net/430/" data-type="post" data-id="430">Coding: Vergleich Strings und Array mit viel Inhalt</a> verwendet.</p>



<p>Warum Events verwenden? Ich habe mal ein Modul erstellt, welches eine Kasse mit einem Bezahlterminal kommuniziert (Kartenzahlung), Während der Kartenzahlung werden diverse Informationen zwischen Kasse und Terminal hin und her gesandt (besonders dann wenn nicht das EC Terminal, sondern die Kasse den Zahlungsbeleg druckt). Damit die Kasse sämtliche Informationen am Kunden und Kassiererdisplay/Monitor anzeigt oder Zahlungsstatis, Start/Ende des Zahlungvorganges, etc. habe ich hier Events verwendet.</p>



<p>Quellcode des Beispiel zum <a href="https://gernardt.net/wp-content/uploads/2025/06/Events_Grundlagen.zip">Download</a>.</p>



<p></p>
<p>Der Beitrag <a href="https://gernardt.net/event-grundlagen/">Event (Grundlagen)</a> erschien zuerst auf <a href="https://gernardt.net"></a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gernardt.net/event-grundlagen/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Delegates (Grundlagen)</title>
		<link>https://gernardt.net/delegates-grundlagen/</link>
					<comments>https://gernardt.net/delegates-grundlagen/#comments</comments>
		
		<dc:creator><![CDATA[Stephan Gernardt]]></dc:creator>
		<pubDate>Wed, 11 Jun 2025 14:59:08 +0000</pubDate>
				<category><![CDATA[Beispielcodes & Erklärungen]]></category>
		<category><![CDATA[Delegate in C#]]></category>
		<category><![CDATA[Grundlagen]]></category>
		<guid isPermaLink="false">https://gernardt.net/?p=788</guid>

					<description><![CDATA[<p>Delegaten ermöglichen es, Methoden als Parameter zu übergeben und sind besonders nützlich für Ereignisse, Rückrufe und flexible Methodenaufrufe. Ein Delegate [&#8230;]</p>
<p>Der Beitrag <a href="https://gernardt.net/delegates-grundlagen/">Delegates (Grundlagen)</a> erschien zuerst auf <a href="https://gernardt.net"></a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Delegaten ermöglichen es, Methoden als Parameter zu übergeben und sind besonders nützlich für Ereignisse, Rückrufe und flexible Methodenaufrufe.</p>



<p>Ein Delegate ist ein Datentyp, der eine Referenz auf Methoden speichern kann, wodurch Methoden wie Parameter behandelt werden können. Dies ermöglicht es, Methoden als Parameter an andere Methoden zu übergeben oder sie in Ereignstrukturen einzusetzen.</p>



<h2 class="wp-block-heading">Kleines Beispiel der Verwendung eines einfachen Delegates</h2>



<pre class="wp-block-code"><code>public delegate int Berechnung(int a, int b);   
// - Definition: Ein Delegate wird ähnlich einer Methode deklariert, lediglich ohne Rumpf

static void Main(string&#91;] args){
    Berechnung addiere = (a, b) => a + b;
    Console.WriteLine("Ergebnis Addition: " + addiere(2, 2));

    Berechnung multipliziere = (c, d) => c * d;
    Console.WriteLine("Ergebnis Multiplikation: " + multipliziere (2, 2));

    Berechnung dividiere = (e, f) => e / f;
    Console.WriteLine("Ergebnis Dividition: " + dividiere(2, 2));

    Berechnung subtrahiere = (g, h) => g - h;
    Console.WriteLine("Ergebnis Subtration: " + subtrahiere(2, 2));
    Console.WriteLine("");
    Console.WriteLine("Zum Beenden Taste drücken");
    var nix = Console.ReadKey();
}</code></pre>



<p><strong>Was macht der obere Code?</strong></p>



<p>Zuerst wird das Delegate mit der Deklaration &#8222;public delegate int Berechnung(int a int b);&#8220; definiert. Das Delegate besitzt keinen Rumpfkörper, sondern lediglich die Parameter, die benötigt werden.<br>Interessant wird es bei der Zeile &#8222;<em>Berechnung addiere = (a, b) => a + b;</em>&#8222;:<br>Es wird eine Variable (<em>addiere</em>) des Delegatentyps Berechnung erstellt. Mit dem Lambda-Ausdruck (<em>(a, b) => a + b</em>) wird festgelegt, was mit den Variablen geschehen soll. In diesem kleinen Beispielprojekt wurde die kompakte Schreibweise gewählt. Lambda-Ausdrücke werden uns im Laufe der Zeit immer wieder begegnen. Innerhalb von Lambda-Ausdrücken können unter anderem auch ganze Methoden definiert werden. Dazu jedoch später mehr. Die Variable <em>addiere</em> ist nun eine Variable, die die Methode speichert. Wird also <em>addiere </em>mit den Parametern aufgerufen, wie in diesem Beispiel <em>addiere(2, 2)</em>, werden die beiden Zahlen entsprechend dem Lambda-Ausdruck addiert.</p>



<p>In dem oben gegebenen Code verwende ich 1 Delegate um Berechnungsoperationen durchzuführen und schreibe per Lambda Funktion die genauen Rechenoperationen (Beispiele => a+b, =>c*d, etc.).</p>



<h2 class="wp-block-heading">Multicast Delegates</h2>



<p>Bei Multicast-Delegates können Delegates Methoden abonnieren, die nacheinander aufgerufen werden.</p>



<p>Für dieses Beispiel erstellen wir einfache Rechenoperationen (wie im Code 1) als Funktionen:</p>



<pre class="wp-block-code"><code>static int MCastAddiere(int a, int b) {
    Console.WriteLine($"Addiere: {a + b}");
    return a + b;
}
static int MCastSubtrahiere(int a, int b){
    Console.WriteLine($"Subtrahiere: {a - b}");
    return a - b;
}
static int MCastMultipliziere(int a, int b){
    Console.WriteLine($"Multipliziere: {a * b}");
    return a - b;
}
static int MCastDividiere(int a, int b){
    Console.WriteLine($"Dividiere: {a / b}");
    return a - b;
}</code></pre>



<p>Um in den Beispielcode zu unterscheiden, habe ich an den Funktionen das Präfix &#8222;<em>MCast</em>&#8220; verwendet.</p>



<p>Als nächsten wird ein Delegate erstellt, mit den Parametern, welche für die Berechnungen verwendet werden;</p>



<pre class="wp-block-code"><code>public delegate int Rechne(int a, int b);</code></pre>



<p>Nun werden wir das Delegat vom Typ Rechne erstellen und alle Funktionen, welche wir ausführen möchten an das Delegat vom Typ Rechne hängen:</p>



<pre class="wp-block-code"><code>Rechne rechner = mCastAddiere;
rechner += mCastSubtrahiere;
rechner += mCastMultipliziere;
rechner += mCastDividiere;</code></pre>



<p>Mit &#8222;<em>+=</em>&#8220; werden Methoden hinzugefügt und mit &#8222;<em>-=</em>&#8220; werden Methoden wieder entfernt.</p>



<p>Und nun Ausführen aller 4 Funktionen das Delegat ausführen:</p>



<pre class="wp-block-code"><code>int ergebnis = rechner(2, 2); // Ausführen aller Funktionen mittels Delegate
Console.WriteLine($"Letztes Ergebnis: {ergebnis}");
Console.WriteLine("Zum Beenden Taste drücken.");
Console.ReadKey();</code></pre>



<p>Wie wir hier sehen, können Multicast-Delegates ein äußerst nützliches Werkzeug sein, um insbesondere wiederholende Aufgaben zu erleichtern. Wenn wir jedoch die Zeile &#8222;<em>Console.WriteLine($&#8220;Letztes Ergebnis: {ergebnis}&#8220;);</em>&#8220; genauer betrachten, stellen wir fest, dass nur das letzte Ergebnis zurückgegeben wird. Daher sollten Multicast-Delegates vor allem bei Methoden mit void-Rückgabewerten verwendet werden, da der aufrufende Code lediglich den Wert der letzten Funktion erhält.</p>



<h2 class="wp-block-heading"><strong>Multicast Delegaten mit Rückgabenwerten</strong></h2>



<p>Das ist etwas knifflig. Im ersten Multi Delegate-Beispiel sehen wir, dass Ergebnisse mit Ausnahme des letzten Ergebnisses verloren gehen. Dies ist in der Praxis nicht immer zielführend. Um später mit &#8222;allen&#8220; Ergebnissen arbeiten zu können, müssen wir etwas Gehirnschmalz einsetzen.</p>



<pre class="wp-block-code"><code>public delegate int Berechnung(int a, int b);

static void Main(string&#91;] args
    int addiere(int a, int b) => a + b;
    int multipliziere(int a, int b) => a * b;
    int dividiere(int a, int b) => a / b;
    int subtrahiere(int a, int b) => a - b;

    Berechnung rechne = addiere;
    rechne += multipliziere;
    rechne += dividiere;
    rechne += subtrahiere;
        
    int&#91;] ergebnisse = rechne 
        .GetInvocationList()
        .Select(d => ((Berechnung)d)(6, 2))
        .ToArray();

    foreach(int ergebnis in ergebnisse)
        Console.WriteLine ($"Ergebnis: {ergebnis}");
    Console.WriteLine("Zum beenden Taste drücken.");
    ConsoleKeyInfo nix = Console.ReadKey();
}</code></pre>



<p>Neu ist hier das Array vom Typ int:</p>



<pre class="wp-block-code"><code>int&#91;] ergebnisse = rechne 
    .GetInvocationList()
    .Select(d => ((Berechnung)d)(6, 2))
    .ToArray();</code></pre>



<p><em>GetInvocationList()</em> gibt ein Array aller im Delegate enthaltenen Methoden zurück. <br>Mit <em>Select(&#8230;)</em> rufen wir gezielt jede Funktion auf, die im Delegate referenziert wird, und erhalten das Ergebnis.<br>Das Array &#8222;<em>ergebnisse</em>&#8220; enthält nun alle Rückgabewerte, auf die wir nach Belieben zugreifen und diese entsprechend verwenden können.</p>



<p>So verlieren wir keinen Rückgabewert mehr.</p>



<p>Hier in diesen Beispielen werden nur Funktionen verwendet die Rechnen, natürlich ist es Möglich mehrere Funktionen zu verwenden, die auch unterschiedliche Dinge mit den Parametern machen.<br></p>



<p>Alle aufgeführten Listenings sind im Beispielprojekt enthalten.</p>



<p>Download zu <a href="https://gernardt.net/wp-content/uploads/2025/06/Delegate_Grundlagen.7z">Grundlagen Delegaten</a></p>



<p></p>
<p>Der Beitrag <a href="https://gernardt.net/delegates-grundlagen/">Delegates (Grundlagen)</a> erschien zuerst auf <a href="https://gernardt.net"></a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gernardt.net/delegates-grundlagen/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Grundlagen Vererbung: Abstrakte Klassen</title>
		<link>https://gernardt.net/grundlagen-vererbung-abstrakte-klassen/</link>
					<comments>https://gernardt.net/grundlagen-vererbung-abstrakte-klassen/#respond</comments>
		
		<dc:creator><![CDATA[Stephan Gernardt]]></dc:creator>
		<pubDate>Thu, 05 Jun 2025 10:13:37 +0000</pubDate>
				<category><![CDATA[Beispielcodes & Erklärungen]]></category>
		<category><![CDATA[abstrakt]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[vererbung]]></category>
		<guid isPermaLink="false">https://gernardt.net/?p=781</guid>

					<description><![CDATA[<p>Abstrakte Klassen bilden die Grundlage für abgeleitete Klassen und stellen ein zentrales Konzept in der objektorientierten Programmierung (OOP) dar. Eine [&#8230;]</p>
<p>Der Beitrag <a href="https://gernardt.net/grundlagen-vererbung-abstrakte-klassen/">Grundlagen Vererbung: Abstrakte Klassen</a> erschien zuerst auf <a href="https://gernardt.net"></a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Abstrakte Klassen bilden die Grundlage für abgeleitete Klassen und stellen ein zentrales Konzept in der objektorientierten Programmierung (OOP) dar. Eine abstrakte Klasse dient als Vorlage, die abstrakte Methoden, Funktionen und Attribute bereitstellt, welche von den abgeleiteten Klassen (Child-Klassen) zwingend implementiert werden müssen.</p>



<ul class="wp-block-list">
<li>Abstrakte Klassen lassen sich nicht direkt instanziieren.</li>



<li>Abstrakte Klassen können sowohl abstrakte als auch nicht-abstrakte Methoden, Funktionen und Attribute umfassen.</li>



<li>Ermöglicht die Wiederverwendung von Quellcode.</li>



<li>Dient als Basis für abgeleitete Klassen.</li>



<li>Abstrakte Klassen dienen dazu, die Implementierung spezifischer Methoden, Funktionen und Attribute in abgeleiteten Klassen verbindlich vorzuschreiben.</li>



<li>Abstrakte Klassen ermöglichen eine klare Struktur im Code, indem sie die direkte Instanziierung verhindern.</li>



<li>Methoden, Funktionen und Attribute der abstrakten Klasse werden in den abgeleiteten Klassen gemeinsam genutzt, was die Wartbarkeit und Struktur des Codes erheblich vereinfacht.</li>
</ul>



<p>Im ersten Teil der <a href="https://gernardt.net/763/" data-type="post" data-id="763">Grundlagen Verebung</a> haben wir ein Beispielprojekt erstellt, das als abstrakte Klasse die Attribute, Methoden und Funktionen eines Fahrzeugs bereitstellt. Abgeleitete (Childs) sind &#8222;Auto&#8220;, &#8222;Motorrad&#8220; und &#8222;LKW&#8220;. In diesem Beispielprojekt wird kurz erläutert, wie Methoden, Funktionen oder Attribute überladen werden können, wie etwa im Beispiel des Motorrads, das nicht rück fahren kann und bei dem die Methode &#8222;FahrenRueckwaerts&#8220; überladen wurde. Sowie die Möglichkeit, je nach Fahrzeugtyp zusätzliche Methoden, Funktionen und Attribute hinzuzufügen (zum Beispiel bei einem LKW Kippen der Fahrerkabine). <br>Wer aufrichtig liest wird am Punkt 2 hängen geblieben sein &#8222;Abstrakte Klassen können sowohl abstrakte als auch nicht-abstrakte Methoden, Funktionen und Attribute umfassen&#8220;. Im Beispielcode sind in der Abstrakten Klasse &#8222;Fahrzeug&#8220; nur nicht-abstrakte Methoden und Attribute verwendet worden. Was sind abstrakte Methoden?</p>



<h2 class="wp-block-heading">Abstrakte Methoden (auch Funktionen und Attribute)</h2>



<ul class="wp-block-list">
<li>Abstrakte Methoden werden nicht in der Basisklasse implementiert, nur die Methodensignatur ist vorhanden.</li>



<li>Abstrakte Methoden müssen mittels Schlüsselwort override in der abgeleiteten Klasse (Child) überschrieben werden.</li>



<li>Abstrakte Methoden können nur in abstrakte Klassen enthalten sein.</li>



<li>Abstrakte Methoden müssen in der abgeleiteten Klasse (Child) implementiert werden.</li>
</ul>



<p>In diesem Teil der Vererbung, werden wir die Klasse Fahrzeug um eine Funktion erweitern. Tanken! Jedes Fahrzeug benötigt Energie, egal ob Wasserstoff, Benzin/Diesel, oder geladen werden muss. Jeder dieser Vorgänge dauert seine Zeit und wird etwas anders ausgeführt und ist nicht bei jedem Fahrzeug gleich. Daher verwende ich mal die Funktion Tanken als Beispiel für abstrakte Funktionen.<br>Zuerst wird in der Abstrakte Klasse die Methoden Signatur festgelegt:</p>



<pre class="wp-block-code"><code>/// &lt;summary>
/// Tanken
/// &lt;/summary>
/// &lt;returns>Bei Erfolg true&lt;/returns>
/// &lt;remarks>
/// Fahrzeuge müssen Tanken.
/// Ob Fossil oder regenerative Stoffe, ob Aufladen oder Wasserstoff, etc.
/// Bei abstrakten Methoden, Funktionen oder Attributen wird kein Code hinterlegt, lediglich die Signatur
/// &lt;/remarks>
public abstract bool Tanken();</code></pre>



<p>Ab sofort ist es obligatorisch, die Funktion Tanken in allen abgeleiteten Klassen zu implementieren. Dadurch kann ich als Programmierer sicherstellen, dass bei neuen Fahrzeugen der oder die nächste Mitarbeiter:in die Funktion Tanken korrekt in neues Fahrzeug integriert.<br>Änderungen in den aktuellen abgeleiteten Klassen (als Beispiel nur die Änderung in der Klasse Auto) :</p>



<pre class="wp-block-code"><code>/// &lt;summary>
/// Auto tanken
/// &lt;/summary>
/// &lt;returns>Bei Erfolg true&lt;/returns>
public override bool Tanken()
{
    Console.WriteLine("Auto links neben der Tanksäule parken.");
    Console.WriteLine("Fahrer steigt aus.");
    Console.WriteLine("Fahrer öffnet Tankdeckel.");
    Console.WriteLine("Wagen wird mit Benzin getankt");
    Console.WriteLine("Fahrer schließt Tankdeckel.");
    Console.WriteLine("Fahrer bezahlt.");
    return true;
}</code></pre>



<p>Eine Funktion Tanken muss nun in jeder abgeleiteten Klasse von &#8222;Fahrzeug&#8220; implementiert werden.<br><a href="https://gernardt.net/wp-content/uploads/2025/06/Grundlagen-Vererbung-Part-02.zip">Download bearbeiteter Code</a> (Visual Studio).</p>



<p>Der Vorteil abstrakter Methoden besteht darin, dass sie eine klare Architektur erzwingen, während die einzelnen abgeleiteten Objekte die Methode entsprechend ihren Bedürfnissen implementieren können. Da die Methoden und Funktionen an die Anforderungen der Objekte angepasst sind, erfolgt auch die Wartung der Methoden und Funktionen innerhalb der abgeleiteten Klassen.</p>
<p>Der Beitrag <a href="https://gernardt.net/grundlagen-vererbung-abstrakte-klassen/">Grundlagen Vererbung: Abstrakte Klassen</a> erschien zuerst auf <a href="https://gernardt.net"></a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gernardt.net/grundlagen-vererbung-abstrakte-klassen/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>DRY Prinzip (Don&#8217;t Repeat Yourself)</title>
		<link>https://gernardt.net/dry-dont-repeat-yourself/</link>
					<comments>https://gernardt.net/dry-dont-repeat-yourself/#respond</comments>
		
		<dc:creator><![CDATA[Stephan Gernardt]]></dc:creator>
		<pubDate>Wed, 04 Jun 2025 18:40:34 +0000</pubDate>
				<category><![CDATA[Beispielcodes & Erklärungen]]></category>
		<category><![CDATA[DRY]]></category>
		<guid isPermaLink="false">https://gernardt.net/?p=775</guid>

					<description><![CDATA[<p>DRY Code ist ein Prinzip der Softwareentwicklung, das darauf abzielt, redundanten Code zu vermeiden. Der Grundgedanke ist, das jede Information [&#8230;]</p>
<p>Der Beitrag <a href="https://gernardt.net/dry-dont-repeat-yourself/">DRY Prinzip (Don&#8217;t Repeat Yourself)</a> erschien zuerst auf <a href="https://gernardt.net"></a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>DRY Code ist ein Prinzip der Softwareentwicklung, das darauf abzielt, redundanten Code zu vermeiden. Der Grundgedanke ist, das jede Information innerhalb eines Systems nur einmal existieren sollte. So können Wartungsarbeiten und Erweiterungen am Code einfacher von statten gehen.</p>



<ul class="wp-block-list">
<li><strong>Wartbarkeit:</strong> Es müssen nur an einer Stelle Änderungen vorgenommen werden.</li>



<li><strong>Strukturiert:</strong> Der Code bleibt übersichtlich und leicht verständlich.</li>



<li><strong>Weniger Fehleranfälligkeit:</strong> Code-Duplikate erhöhen das Risiko inkonsistente Änderungen.</li>
</ul>



<h2 class="wp-block-heading">Beispiel Non DRY Code (schlecht umgesetzt)</h2>



<p>Beispiel einer einfachen Steuerberechnung mit einem festen Steuersatz von 19 %, ohne Berücksichtigung weiterer Steuerstufen (wie 7 %, 0 % oder 10,7 % ab 2025 liegt der Steuersatz für land- und forstwirtschaftliche Betriebe gemäß der Durchschnittsbesteuerung nach § 24 UStG bei 7,8 %, da er schrittweise gesenkt wurde).</p>



<pre class="wp-block-code"><code>public class Rechnung {
        /// &lt;summary>
        /// Volle USt aus dem Nettobetrag berechnen
        /// &lt;/summary>
        /// &lt;param name="Betrag">Nettobetrag&lt;/param>
        /// &lt;returns>USt Betrag&lt;/returns>
        public double BerechneSteuer(double Betrag) {
            return Betrag * 0.19;
        }
        /// &lt;summary>
        /// Bruttobetrag der Rechnung
        /// &lt;/summary>
        /// &lt;param name="Betrag">Nettobetrag&lt;/param>
        /// &lt;returns>Bruttobetrag&lt;/returns>
        public double Bruttobetrag(double Betrag) {
            return Betrag * BerechneSteuer(84.03);
        }
    }

    public class Bon
    {
        /// &lt;summary>
        /// Volle USt aus dem Nettobetrag berechnen
        /// &lt;/summary>
        /// &lt;param name="Betrag">Nettobetrag&lt;/param>
        /// &lt;returns>USt Betrag&lt;/returns>
        public double BerechneSteuer(double Betrag)
        {
            return Betrag * 0.19;
        }
        /// &lt;summary>
        /// Bruttobetrag des Bons
        /// &lt;/summary>
        /// &lt;param name="Betrag">Nettobetrag&lt;/param>
        /// &lt;returns>Bruttobetrag&lt;/returns>
        public double Bruttobetrag(double Betrag)
        {
            return Betrag * BerechneSteuer(84.03);
        }
    }
    public class Einkauf
    {
        /// &lt;summary>
        /// Volle USt aus dem Nettobetrag berechnen
        /// &lt;/summary>
        /// &lt;param name="Betrag">Nettobetrag&lt;/param>
        /// &lt;returns>USt Betrag&lt;/returns>
        public double BerechneSteuer(double Betrag)
        {
            return Betrag * 0.19;
        }
        /// &lt;summary>
        /// Bruttobetrag des Einkaufs
        /// &lt;/summary>
        /// &lt;param name="Betrag">Nettobetrag&lt;/param>
        /// &lt;returns>Bruttobetrag&lt;/returns>
        public double Bruttobetrag(double Betrag)
        {
            return Betrag * BerechneSteuer(84.03);
        }
    }</code></pre>



<h2 class="wp-block-heading">Beispiel DRY Prinzip</h2>



<pre class="wp-block-code"><code>    public class Berechnungen
    {
        /// &lt;summary>
        /// Volle USt aus dem Nettobetrag berechnen
        /// &lt;/summary>
        /// &lt;param name="Betrag">Nettobetrag&lt;/param>
        /// &lt;returns>USt Betrag&lt;/returns>
        public static double BerechneSteuer(double Betrag)
        {
            return Betrag * (double)0.19;
        }
    }
    public class Rechnung
    {
        /// &lt;summary>
        /// Bruttobetrag der Rechnung
        /// &lt;/summary>
        /// &lt;param name="Betrag">Nettobetrag&lt;/param>
        /// &lt;returns>Bruttobetrag&lt;/returns>
        public double Bruttobetrag(double Betrag)
        {
            return Betrag * Berechnungen.BerechneSteuer(84.03);
        }
    }

    public class Bon
    {
        /// &lt;summary>
        /// Bruttobetrag des Bons
        /// &lt;/summary>
        /// &lt;param name="Betrag">Nettobetrag&lt;/param>
        /// &lt;returns>Bruttobetrag&lt;/returns>
        public double Bruttobetrag(double Betrag)
        {
            return Betrag * Berechnungen.BerechneSteuer(84.03);
        }
    }
    public class Einkauf
    {
        /// &lt;summary>
        /// Bruttobetrag des Einkaufs
        /// &lt;/summary>
        /// &lt;param name="Betrag">Nettobetrag&lt;/param>
        /// &lt;returns>Bruttobetrag&lt;/returns>
        public double Bruttobetrag(double Betrag)
        {
            return Betrag * Berechnungen.BerechneSteuer(84.03);
        }
    }</code></pre>



<h2 class="wp-block-heading">Unterschiede zwischen beiden Listenings</h2>



<p>Non DRY Code:<br>Im Non-DRY-Ansatz wird der reguläre Steuerbetrag (19 %) sowohl in den Klassen für Rechnungen, Einkauf und Bons separat berechnet. Ändert sich der Steuersatz, muss die Anpassung an mehreren Stellen vorgenommen werden – für Rechnung, Einkauf und Bon. Falls zusätzlich eine Angebotsberechnung hinzugefügt wird, müsste die Steuerlogik ein weiteres Mal programmiert oder kopiert werden, was die Wartung erschwert.</p>



<p>DRY Code:<br>Im DRY-Code wird die Berechnungsfunktion zentral definiert. Diese Funktion wird in den Klassen Einkauf, Rechnung und Bon verwendet. Ändert sich der Steuersatz, muss die Funktion nur an einer Stelle angepasst werden, wodurch der Code wartungsfreundlicher bleibt.</p>



<p>Info:<br>Im Normalfall werden Steuersätze nicht fest im Code hinterlegt, da sie sich mit der Zeit ändern und für verschiedene Artikel unterschiedlich gelten können. Ein Beispiel dafür ist die Besteuerung in einem Schnellrestaurant: Speisen, die im Restaurant verzehrt werden, unterliegen dem regulären Steuersatz von 19 %, während außer Haus verkaufte Speisen mit dem ermäßigten Steuersatz von 7 % besteuert werden.</p>
<p>Der Beitrag <a href="https://gernardt.net/dry-dont-repeat-yourself/">DRY Prinzip (Don&#8217;t Repeat Yourself)</a> erschien zuerst auf <a href="https://gernardt.net"></a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gernardt.net/dry-dont-repeat-yourself/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
