C-Sharp-Programmierung: Unterschied zwischen den Versionen

Aus Flinkwiki
Wechseln zu: Navigation, Suche
(Die Seite wurde neu angelegt: „ <div align="right">'''Zur Startseite "Fachinformatiker"'''</div> <div align="right">'''Zur Seite C-Programmierung''…“)
 
 
(Eine dazwischenliegende Version desselben Benutzers wird nicht angezeigt)
Zeile 1: Zeile 1:
 
+
<div align="right"><big>'''[https://flinkwiki.de/index.php?title=Kategorie:Alle_Seiten Seitenübersicht]'''</big></div>
 
 
<div align="right">'''[[Fachinformatiker|Zur Startseite "Fachinformatiker"]]'''</div>
 
 
<div align="right">'''[[C-Programmierung|Zur Seite C-Programmierung]]'''</div>
 
<div align="right">'''[[C-Programmierung|Zur Seite C-Programmierung]]'''</div>
 
<div align="right">'''[[UML|Zur Seite UML]]'''</div>
 
<div align="right">'''[[UML|Zur Seite UML]]'''</div>
Zeile 1.713: Zeile 1.711:
 
}
 
}
 
</nowiki>
 
</nowiki>
 +
 +
----
 +
 +
== Mono ==
 +
 +
Installation in Ubuntu:
 +
 +
apt install apt-transport-https dirmngr
 +
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
 +
echo "deb https://download.mono-project.com/repo/ubuntu vs-bionic main" | sudo tee /etc/apt/sources.list.d/mono-official-vs.list
 +
sudo apt update
 +
apt install monodevelop
 +
[https://www.monodevelop.com/download/]
  
 
----
 
----

Aktuelle Version vom 15. August 2020, 20:51 Uhr

Seitenübersicht
Zur Seite C-Programmierung
Zur Seite UML
Zur Seite Snaps Library

Grundlagen der Sprache C#

Variable


Konstante

using System;

namespace Constant
{
    class Program
    {
        enum Days { Sat, Sun, Mon, Tue, Wed, Thu, Fri, };

        static void Main(string[] args)
        {
            Console.Title = "Constant";

            const double pi = 3.14159265358979;
            var daysType = typeof(Days);

            Console.WriteLine("Pi Type: " + pi.GetType());
            Console.WriteLine("Circumference: " + (pi * 3));

            Console.WriteLine("\nFirst Name: " + Days.Sat);
            Console.WriteLine("1st Index: " + (int)Days.Sat);

            string name = Enum.GetName(daysType, 1);
            Console.WriteLine("\n2nd Index: " + name);
            bool flag = Enum.IsDefined(daysType, "Mon");
            Console.WriteLine("Contains Mon?: " + flag);
            Console.ReadKey();
        }
    }
}

C# Programming in easy steps


Array

            int[] tab = new int[7];
            int[] tab2 = new int[4] {1,2,3,4};
            double[] dtab = new double[3];


            tab[3] = 17;
            Console.WriteLine("----------------------------\n");
            dtab[1] = 4.5;

            Console.WriteLine("tab[0] = {0}", tab[0]);
            Console.WriteLine("tab[3] = {0}", tab[3]);
            Console.WriteLine("----------------------------\n");
            Console.WriteLine("dtab[0] = {0}", dtab[0]);
            Console.WriteLine("dtab[1] = {0}", dtab[1]);
            Console.WriteLine("----------------------------\n");

            string[] strArr = new String[2];
            strArr[0] = "C# ";
            strArr[1] = "macht Spaß!";
            Console.Write(strArr[0]);
            Console.WriteLine(strArr[1]);

            char[] ctab = new char[7] {'a','b','c','d','e','f','g'};

            int[,] point = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } };



Mehrdimensionales Array und Ragged Array

			int[,] elements = {{1,2,3},{3,2,7},{5,-1,2},{1,9,9},{11,17,-10}};
			Console.WriteLine(elements.GetLength(1));
			Console.WriteLine(elements.GetLength(0));
			Console.WriteLine("Länge = {0}", elements.Length);

			//int[][] myArray = new int[4][];
			//myArray[0] = new int[3];
			//myArray[1] = new int[4];
			//myArray[2] = new int[2];
			//myArray[3] = new int[5];

			//myArray[0] = new int[3] { 1, 2, 3 };
			//myArray[1] = new int[4] { 1, 2, 3, 4 };
			//myArray[2] = new int[2] { 1, 2 };
			//myArray[3] = new int[5] { 1, 2, 3, 4, 5 };

			int[][] myArray = { new int[]{1,2,3},
				new int[]{1,2,3,4},
				new int[]{1,2},
				new int[]{1,2,3,4,5}};

			Console.WriteLine(myArray[3][4]);

			myArray.ToList().ForEach(e => Console.WriteLine(string.Join(",", e)));


Klasse List

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace B_05_List
{
    class Program
    {
        static void Main(string[] args)
        {
            List<double> tab = new List<double>();
            tab.Add(2.5);
            tab.Add(1.6);
            tab.Add(8.2);
            tab.Add(3.5);
            tab.Add(6.7);

            Zeige(tab);

            tab.Sort();

            Zeige(tab);

            tab.Reverse();

            Zeige(tab);

            Console.WriteLine(tab[3]);
            tab.Insert(2,33.7);

            Zeige(tab);

            tab.Add(77.77);

            Zeige(tab);

            tab.Remove(8.2);

            Zeige(tab);

            tab.RemoveAt(0);

            Zeige(tab);

        }

        static void Zeige(List<double> t)
        {
            foreach (double ak in t)
            {
                Console.Write("{0} ", ak);
            }
            Console.WriteLine();    //CR+LF
        }
    }
}


Ausnahmen abfangen mit try ... catch

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Application
{
	class MainClass
	{
		public static void Main (string[] args)
		
		{	
			int zahl = 100;
			int Marke;
			do
			{
				Marke = 0;

				try
				{ 
					Console.Write("Geben Sie eine Zahl zwischen 0 und 9 ein: ");
					zahl = Convert.ToInt32(Console.ReadLine());
				}
				catch 
				{
					Console.WriteLine("Sie sollen die Zahl eingeben!!!\n");
					Marke = 1;
				}
				if (zahl > 9 || zahl < 0)
				{
					Console.WriteLine("Ihre Zahl ist unzulässig.\n");
					Console.Write("Versuchen Sie es erneut.\n");
					Marke = 1;
				}
			} while (Marke == 1);		
		
		}
	}
}


Int32.TryParse-Methode: (String, Int32)

Konvertiert die Zeichenfolgendarstellung einer Zahl in die entsprechende 32-Bit-Ganzzahl mit Vorzeichen. Ein Rückgabewert gibt an, ob die Konvertierung erfolgreich abgeschlossen wurde.

public static bool TryParse(
	string s,
	out int result
)

[1]



Random.Next-Methode: (Int32, Int32)

Gibt eine Zufallsganzzahl zurück, die in einem angegebenen Bereich liegt.

public virtual int Next(
	int minValue,
	int maxValue
)

[2]

Random rnd = new Random(DateTime.Now.Millisecond);

String mit ToUpper in Großbuchstaben umwandeln

       string name;
       name = SnapsEngine.ReadString("What is your name?");
       string upperCaseName = name.ToUpper();



Strings vergleichen

String.Compare-Methode: (String, String, Boolean): https://msdn.microsoft.com/de-de/library/zkcaxw5y(v=vs.110).aspx

Wert Bedingung
Kleiner als 0 (Null) strA steht in der Sortierreihenfolge vor strB.
0 (Null) strA tritt in der Sortierreihenfolge an der gleichen Position wie strB auf.
Größer als 0 (Null) strA steht in der Sortierreihenfolge hinter strB.
if (string.Compare (n1, n2) < 0) {	}

Klassendesign

Klassen erzeugen

        static void Main(string[] args)
        {
            Person Meyer = new Person();
            Person Doell = new Person();
            Meyer.Name = "Meyer";
            Meyer.Alter = 20;
            Doell = Meyer;
            Doell.Name = "Döll";
            Doell.Alter = 10;
            Meyer = null;

            long value1 = 64;
            long value2 = value1;
            value1 = 32;

        }
    }



    class Person
    {
        public string Name;
        public int Alter;

        public Person()
        {
            Name = "";
            Alter = 0;
        }

        public void Gehen()
        {
            Aufstehen();
        }

        private void Aufstehen()
        { 
        
        }


Methoden

		public static void Main (string[] args)
		{	

			int input = ReadInput();

			input = Calculate (input);

			Output (input);



		}

		static int ReadInput()
		{
			Console.WriteLine ("Zahl eingeben");
//			string strInput = Console.ReadLine();
//			int input = Convert.ToInt32(strInput);
			int pput = Convert.ToInt32 (Console.ReadLine ());
			return pput;
		}

		static int Calculate(int var)
		{
			var = var + 5;
			var = var / 2;
			var = var * 3;
			return var;
		}

		static void Output (int sihi)
		{
			Console.WriteLine ("Ergebins: " + sihi);



Datenkapselung

using System;

namespace B_02_Circle
{
    class Program
    {
        static void Main(string[] args)
        {
            Circle c1 = new Circle();
            c1.Radius = 7;
            c1.XCoordinate = 4.2;
            c1.YCoordinate = -3.7;
            Circle c2 = new Circle();
            c2.Radius = 15;
            c2.XCoordinate = 6.5;
            c2.YCoordinate = -7.7;
            //c1._Radius = 6;  Fehler!!!
            c1.GetArea();
            c1.GetCircumference();

        }
    }

    public class Circle
    {
        private int _Radius;    //Datenkapselung
        public double XCoordinate { get; set; }
        public double YCoordinate { get; set; }
        
        public int Radius
        {
            get { return _Radius; }
            set
            {
                if (value >= 0)
                    _Radius = value;
                else
                    Console.Write("Unzulässiger negativer Wert.");
            }
        }

        // Methoden

        public double GetArea()
        {
            double area = Math.Pow(Radius, 2) * Math.PI;
            return area;
        }

        public double GetCircumference()
        {
            double circumference = 2 * Radius * Math.PI;
            return circumference;
        }
    }
}



mit den Methoden Move und Bigger, Zahlen als decimal

using System;

namespace B_02_Circle
{
    class Program
    {
        static void Main(string[] args)
        {
            Circle c1 = new Circle();
            c1.Radius = 7.3M;
            c1.XCoordinate = 4.2M;
            c1.YCoordinate = -3.7M;
            Circle c2 = new Circle();
            c2.Radius = 7.3M;
            c2.XCoordinate = 6.5M;
            c2.YCoordinate = -7.7M;
            //c1._Radius = 6;  Fehler!!!
            Console.WriteLine("Fläche = {0}",c1.GetArea() );
            Console.WriteLine("Umfang = {0}", c1.GetCircumference());
            c1.Move(2.4M,-3.1M);
            c2.Move(3.7M, -1.2M, -12.3M);
            Console.WriteLine(c1.Bigger(c2));

        }
    }

    public class Circle
    {
        private decimal _Radius;    //Datenkapselung
        public decimal XCoordinate { get; set; }
        public decimal YCoordinate { get; set; }
        
        public decimal Radius
        {
            get { return _Radius; }
            set
            {
                if (value >= 0)
                    _Radius = value;
                else
                    Console.Write("Unzulässiger negativer Wert.");
            }
        }

        // Methoden

        public decimal GetArea()
        {
            decimal area = Radius * Radius * (decimal)Math.PI;
            return area;
        }

        public decimal GetCircumference()
        {
            decimal circumference = 2.0M * Radius * (decimal)Math.PI;
            return circumference;
        }

        public void Move(decimal dx, decimal dy)
        {
            XCoordinate += dx;
            YCoordinate += dy;
        }

        public void Move(decimal dx, decimal dy, decimal dRadius)
        {
            Move(dx, dy); 
            Radius += dRadius;
        }

        public int Bigger(Circle kreis)
        {
            if (this.Radius > kreis.Radius) return 1;
            if (this.Radius < kreis.Radius) return -1;
            return 0;
        }
    }
}



Call by Reference mit dem Modifizierer "out"

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Application
{
	class Program
	{
		static void Main(string[] args)
		{
			int value;
			DoSomething(out value);
			Console.WriteLine("value = {0}", value);
			Console.ReadLine();

		}

		static void DoSomething(out int param)
		{
			param = 550;
		}

	}
}
	


Übergabe von Objekten

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Application
{
	class Program
	{
		static void Main(string[] args)
		{
			Demo1 object1 = new Demo1();
			Demo2 object2 = new Demo2();
			object2.ChangeValue(object1);
			Console.WriteLine(object1.Value);
			Console.ReadLine();
		}
	}

	class Demo1
	{
		public int Value = 500;
		public int xyz = 3;
	}

	class Demo2
	{
		public void ChangeValue(Demo1 @object)
		{
			@object = new Demo1();
			@object.Value =  4711;
		}
	}
}


... mit Call by Referenz:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Application
{
	class Program
	{
		static void Main(string[] args)
		{
			Demo1 object1 = new Demo1();
			Demo2 object2 = new Demo2();
			object2.ChangeValue(ref object1);
			Console.WriteLine(object1.Value);
			Console.ReadLine();
		}
	}

	class Demo1
	{
		public int Value = 500;
		public int xyz = 3;
	}

	class Demo2
	{
		public void ChangeValue(ref Demo1 @object)
		{
			@object = new Demo1();
			@object.Value =  4711;
		}
	}
}
	

Beispiel Bruchrechner

using System;

namespace Bruch_Rechner
{
    class Program
    {
        static void Main(string[] args)
        {

            Bruch Eb = new Bruch();
            Bruch B1 = new Bruch(1, 2);
            Bruch B2 = new Bruch(2, 3);
            Bruch B3 = new Bruch(0, 3);
            Eb = B1.Add(B2);
            Eb.Ausgabe();
            Eb = B1.Div(B3);

        }

        class Bruch
        {
            //Attribute - Felder
            private int _Zaehler;
            private int _Nenner;

            //Eigenschaftsmethoden
            public int Zaehler
            {
                get { return _Zaehler; }
                set { _Zaehler = value; }
            }

            public int Nenner
            {
                get { return _Nenner; }
                set
                {
                    if (value != 0)
                        _Nenner = value;
                    else
                        Console.WriteLine("Nenner darf nicht 0 sein.");
                }
            }

            //Konstruktoren
            public Bruch() : this(0, 1) { }
            public Bruch(int z, int n)
            {
                Zaehler = z;
                Nenner = n;
            }

            //Methoden

            //Instanzmethoden
            public void Ausgabe()
            {
                Console.WriteLine("( {0} : {1} )", this.Zaehler, this.Nenner);
            }

            public Bruch Add(Bruch b)
            {
                Bruch eb = new Bruch();
                eb.Zaehler = this.Zaehler * b.Nenner + b.Zaehler * this.Nenner;
                eb.Nenner = this.Nenner * b.Nenner;

                int t = ggT(eb.Zaehler, eb.Nenner);

                eb.Zaehler /= t;
                eb.Nenner /= t;

                return eb;
            }

            public Bruch Sub(Bruch b)
            {
                Bruch eb = new Bruch();
                eb.Zaehler = this.Zaehler * b.Nenner - b.Zaehler * this.Nenner;
                eb.Nenner = this.Nenner * b.Nenner;

                int t = ggT(eb.Zaehler, eb.Nenner);

                eb.Zaehler /= t;
                eb.Nenner /= t;

                return eb;
            }

            public Bruch Mul(Bruch b)
            {
                Bruch eb = new Bruch();
                eb.Zaehler = this.Zaehler * b.Zaehler;
                eb.Nenner = this.Nenner * b.Nenner;

                int t = ggT(eb.Zaehler, eb.Nenner);

                eb.Zaehler /= t;
                eb.Nenner /= t;

                return eb;
            }

            public Bruch Div(Bruch b)
            {
                Bruch eb = new Bruch();
                if (b.Zaehler != 0)
                {
                    eb.Zaehler = this.Zaehler * b.Nenner;
                    eb.Nenner = this.Nenner * b.Zaehler;

                    int t = ggT(eb.Zaehler, eb.Nenner);

                    eb.Zaehler /= t;
                    eb.Nenner /= t;

                    return eb;
                }
                else
                {
                    Console.WriteLine("Fehler!!!\nDivision durch Null.");
                    eb.Zaehler = 0;
                    eb.Nenner = 1;

                    return eb;
                }

            }

            //Klassenmethoden
            // ggT Modulo + tauschen
            public static int ggT(int z, int n)
            {
                z = Math.Abs(z);
                n = Math.Abs(n);
                int r;
                while (n != 0)
                {
                    r = z % n;
                    z = n;
                    n = r;
                }
                return Math.Abs(z);
            }

            public static void Ausgabe(Bruch b)
            {
                Console.WriteLine("( {0} : {1} )", b.Zaehler, b.Nenner);
            }

            public static Bruch Add(Bruch a, Bruch b)
            {
                Bruch eb = new Bruch();
                eb.Zaehler = a.Zaehler * b.Nenner + b.Zaehler * a.Nenner;
                eb.Nenner = a.Nenner * b.Nenner;

                int t = ggT(eb.Zaehler, eb.Nenner);

                eb.Zaehler /= t;
                eb.Nenner /= t;

                return eb;
            }

            public static Bruch Sub(Bruch a, Bruch b)
            {
                Bruch eb = new Bruch();
                eb.Zaehler = a.Zaehler * b.Nenner - b.Zaehler * a.Nenner;
                eb.Nenner = a.Nenner * b.Nenner;

                int t = ggT(eb.Zaehler, eb.Nenner);

                eb.Zaehler /= t;
                eb.Nenner /= t;

                return eb;
            }

            public static Bruch Mul(Bruch a, Bruch b)
            {
                Bruch eb = new Bruch();
                eb.Zaehler = a.Zaehler * b.Zaehler;
                eb.Nenner = a.Nenner * b.Nenner;

                int t = ggT(eb.Zaehler, eb.Nenner);

                eb.Zaehler /= t;
                eb.Nenner /= t;

                return eb;
            }

            public static Bruch Div(Bruch a, Bruch b)
            {
                Bruch eb = new Bruch();
                if (b.Zaehler != 0)
                {
                    eb.Zaehler = a.Zaehler * b.Nenner;
                    eb.Nenner = a.Nenner * b.Zaehler;

                    int t = ggT(eb.Zaehler, eb.Nenner);

                    eb.Zaehler /= t;
                    eb.Nenner /= t;

                    return eb;
                }
                else
                {
                    Console.WriteLine("Fehler!!!\nDivision durch Null.");
                    eb.Zaehler = 0;
                    eb.Nenner = 1;

                    return eb;
                }
            }
        }
    }
}


Beispiel Geo (Kugel)

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace B_01_Geo_v2
{
    class Program
    {
        static void Main(string[] args)
        {
            Kugel ku3 = new Kugel(4.6, 2.9, 3.7, 4.7);
            Kugel ku4 = new Kugel(4.6, 2.9, 3.7, 4.7);
            Kugel ku5 = new Kugel(4.6, 2.9, 3.7, 4.7);
            
            Geo punkt1 = new Geo(3.0, 0.7);
            Geo punkt2 = new Geo();
            punkt2.Move(0.4, -2.7);
            punkt2.XCoordinate += 3.9;
            punkt2.YCoordinate += 1.3;

            Kreis kr1 = new Kreis(5.7, -20.4, 10.3);
            Kreis kr2 = new Kreis(3.4, -10.2, 11.9);
            kr1.Ausgabe();
            kr2.Ausgabe();
            Console.WriteLine("Fläche bei R={0} beträgt: {1} ", kr1.Radius, kr1.GetArea());
            Console.WriteLine("Umfang bei R={0} beträgt: {1} ", kr1.Radius, kr1.GetCircumference());
            Console.WriteLine("Fläche bei R={0} beträgt: {1} ", kr2.Radius, kr2.GetArea());
            Console.WriteLine("Umfang bei R={0} beträgt: {1} ", kr2.Radius, kr2.GetCircumference());
            Console.WriteLine(kr1.Bigger(kr2));
            kr1.Move(1.6, 2.3);
            kr1.Ausgabe();

            Console.WriteLine(new string('=',26));
            
            Rechteck r1 = new Rechteck(20.0, 1.0);
            Rechteck r2 = new Rechteck(10.0, 10.0);
            r1.Ausgabe();
            r2.Ausgabe();
            Console.WriteLine(r1.Bigger(r2));
            ku3.Ausgabe();
        }
    }
}


Geo.cs

namespace B_01_Geo_v2
{
    class Geo
    {
        public double XCoordinate { get; set; }     //Eigenschaftsmethode
        public double YCoordinate { get; set; }     //Eigenschaftsmethode

        //Konstruktoren
        public Geo()
            : this(0.0, 0.0)
        { }

        public Geo(double x, double y)
        {
            XCoordinate = x;
            YCoordinate = y;
        }

        public void Move(double dx, double dy)
        {
            XCoordinate += dx;
            YCoordinate += dy;
        }
    }
}



Kreis.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace B_01_Geo_v2
{
    class Kreis : Geo       //Basisklasse heißt Geo
    {
        protected double _Radius;     //Eigenschaft
        public double Radius        //Eigenschaftsmethode
        {
            get { return _Radius; }
            set
            {
                if (value >= 0.0)
                    _Radius = value;
                else
                {
                    Console.WriteLine("{0} ist ein unzulässiger negativer Radiuswert!!!\nRadius bekommt einen Wert 0.0 !!!");
                    _Radius = 0.0;
                }
            }
        }

        //Statische Elemente (Klassenelemente)
        protected static int _CountKreis;
        public static int CountKreis
        {
            get { return _CountKreis; }
        }

        //Konstruktoren +2 Überladen
        public Kreis()
            : this(0.0, 0.0, 0.0) { }

        public Kreis(double r)
            : this(r, 0.0, 0.0) { }
        
        public Kreis(double r, double x, double y) : base(x, y)
        {
            Radius = r;
            Kreis._CountKreis++;    //weil CountKreis keine set-Komponente hat 
        }

        //Instanzmethoden
        public double GetArea()
        {
            return Math.PI * this.Radius * this.Radius;
        }

        public double GetCircumference()
        {
            return 2 * Math.PI * this.Radius;
        }

        public int Bigger(Kreis k)
        {
            if (k == null || this.Radius > k.Radius) return 1;
            if (this.Radius < k.Radius) return -1;
            return 0;
        }

        public void Ausgabe()
        {
            Console.WriteLine("Kreis: R={0} X={1} Y={2}", Radius, XCoordinate, YCoordinate);
        }
    }
}


Kugel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace B_01_Geo_v2
{
    class Kugel : Kreis
    {
        public double ZCoordinate { get; set; }

        //Statische Elemente (Klassenelemente)
        private static int _CountKugel;
        public static int CountKugel
        {
            get { return _CountKugel; }
        }

        //Konstruktoren +2 Überladen
        public Kugel()
            : this(0.0, 0.0, 0.0, 0.0) { }

        public Kugel(double r)
            : this(r, 0.0, 0.0, 0.0) { }

        public Kugel(double r, double x, double y, double z) : base(r, x, y)
        {
            //Radius = r;
            //XCoordinate = x;
            //YCoordinate = y;
            ZCoordinate = z;
            Kugel._CountKugel++;    //weil CountKreis keine set-Komponente hat 
            Kreis._CountKreis--;
        }

        //Instanzmethoden
        public double GetVolumen()
        {
            return Radius * GetArea() / 3.0;    //GetArea von der Klasse Kugel
            //return Radius * Radius * Radius * Math.PI * 4.0 / 3;
        }

        new public double GetArea()
        {
            return 4.0 * base.GetArea();    
            //return 4.0 * Math.PI * this.Radius * this.Radius;
        }

        new public double GetCircumference()
        {
            return base.GetCircumference();
            //return 2 * Math.PI * this.Radius;
        }

        public int Bigger(Kugel kg)
        {
            if (kg == null || this.Radius > kg.Radius) return 1;
            if (this.Radius < kg.Radius) return -1;
            return 0;
        }

        new public void Ausgabe()
        {
            Console.WriteLine("Kugel: R={0} X={1} Y={2} Z={3}", Radius, XCoordinate, YCoordinate, ZCoordinate);
        }

    }


}


Schnittstelle (Interface)

Eine Schnittstelle sieht aus wie eine Klasse, enthält aber nur Definitionen, keinen Programmcode. Somit können von einer Schnittstelle keine Objekte erzeugt werden. Schnittstellen werden erste dann aktiviert, wenn sie von einer Klasse verwendet bzw. implementiert werden.

    public interface IRegeln



Dictionary

Beispiel Syntax Dictionary:

           public class UserMenue
    {
        Dictionary<char, string> Auswahl = new Dictionary<char, string>
        {
            {'A',"Starten  "},
            {'P',"Pause" },
            {'E',"Beenden" }
        };


// When you use foreach to enumerate dictionary elements,
// the elements are retrieved as KeyValuePair objects.
Console.WriteLine();
foreach( KeyValuePair<string, string> kvp in openWith )
{
    Console.WriteLine("Key = {0}, Value = {1}", 
        kvp.Key, kvp.Value);
}

[3]


Assoziative Arrays:

  • Das assoziative Datenfeld (englisch map, dictionary oder associative array) ist eine Datenstruktur, die – anders als ein gewöhnliches Feld (engl. array) – nichtnumerische (oder nicht fortlaufende) Schlüssel (zumeist Zeichenketten) verwendet, um die enthaltenen Elemente zu adressieren; diese sind in keiner festgelegten Reihenfolge abgespeichert. Idealerweise werden die Schlüssel so gewählt, dass eine für die Programmierer nachvollziehbare Verbindung zwischen Schlüssel und Datenwert besteht. [4]

Delegaten

A delegate is a type that represents references to methods with a particular parameter list and return type. When you instantiate a delegate, you can associate its instance with any method with a compatible signature and return type. You can invoke (or call) the method through the delegate instance.

Delegates are used to pass methods as arguments to other methods. Event handlers are nothing more than methods that are invoked through delegates. You create a custom method, and a class such as a windows control can call your method when a certain event occurs. The following example shows a delegate declaration:

public delegate int PerformCalculation(int x, int y);

[5]

https://msdn.microsoft.com/de-de/library/aa288459(v=vs.71).aspx

http://www.dotnetdojo.com/delegates-csharp/



Events / Ereignisse

Ein Ereignis ist eine Meldung, die von einem Objekt gesendet wird, um das Auftreten einer Aktion zu signalisieren. Die Aktion kann durch Benutzerinteraktion, wie das Anklicken einer Schaltfläche, verursacht werden, oder sie kann durch eine andere Programmlogik, wie das Ändern eines Eigenschaftswerts, ausgelöst werden. Das Objekt, von dem das Ereignis ausgelöst wird, wird als Ereignissender bezeichnet. Dem Ereignissender ist nicht bekannt, welches Objekt oder welche Methode die ausgelösten Ereignisse empfangen (behandeln) wird. Das Ereignis ist in der Regel ein Member des Ereignissenders. Beispielsweise ist das Click-Ereignis ein Member der Klasse Button, und das PropertyChanged-Ereignis ist ein Member der Klasse, von der die INotifyPropertyChanged-Schnittstelle implementiert wird.[6] Einfaches Beispiel



Lambda-Ausdrücke

Ein Lambdaausdruck ist eine anonyme Funktion, mit der Typen für Delegaten oder die Ausdrucksbaumstruktur erstellt werden können. Mit Lambda-Ausdrücken können lokale Funktionen geschrieben werden, die als Argumente übergeben oder als Wert von Funktionsaufrufen zurückgegeben werden können. Lambda-Ausdrücke sind besonders für das Schreiben von LINQ-Abfrageausdrücken hilfreich.

Zum Erstellen eines Lambdaausdrucks geben Sie Eingabeparameter (falls vorhanden) auf der linken Seite des Lambda-Operators => an und stellen den Ausdruck oder den Anweisungsblock auf die andere Seite. Beispielsweise gibt der Lambda-Ausdruck x => x * x einen Parameter an, der x heißt und den Wert x quadriert zurückgibt. Dieser Ausdruck kann einem Delegattyp zuwiesen werden, wie im folgenden Beispiel dargestellt:

delegate int del(int i);  
static void Main(string[] args)  
{  
    del myDelegate = x => x * x;  
    int j = myDelegate(5); //j = 25  
}  
[7]



ReadKey

               ConsoleKeyInfo eingabe = Console.ReadKey(true); // kein echo der Eingabe 

ConsoleKeyInfo: Beschreibt die Konsolentaste, die gedrückt wurde, einschließlich des durch die Konsolentaste dargestellten Zeichens und des Zustands der Modifizierertasten UMSCHALTTASTE, ALT und STR.

Console.ReadKey: Ruft die nächste vom Benutzer gedrückte Zeichen- oder Funktionstaste ab. Die gedrückte Taste wird optional im Konsolenfenster angezeigt. Ausnahmen: System.InvalidOperationException


using System;
using System.Text;

public class ConsoleKeyExample
{
   public static void Main()
   {
      ConsoleKeyInfo input;
      do {
         Console.WriteLine("Press a key, together with Alt, Ctrl, or Shift.");
         Console.WriteLine("Press Esc to exit.");
         input = Console.ReadKey(true);

         StringBuilder output = new StringBuilder(
                       String.Format("You pressed {0}", input.Key.ToString()));
         bool modifiers = false;

         if ((input.Modifiers & ConsoleModifiers.Alt) == ConsoleModifiers.Alt) {
            output.Append(", together with " + ConsoleModifiers.Alt.ToString());
            modifiers = true;
         }
         if ((input.Modifiers & ConsoleModifiers.Control) == ConsoleModifiers.Control)
         {
            if (modifiers) {
               output.Append(" and ");
            }   
            else {
               output.Append(", together with ");
               modifiers = true;
            }
            output.Append(ConsoleModifiers.Control.ToString());
         }
         if ((input.Modifiers & ConsoleModifiers.Shift) == ConsoleModifiers.Shift)
         {
            if (modifiers) {
               output.Append(" and ");
            }   
            else {
               output.Append(", together with ");
               modifiers = true;
            }
            output.Append(ConsoleModifiers.Shift.ToString());
         }
         output.Append(".");                  
         Console.WriteLine(output.ToString());
         Console.WriteLine();
      } while (input.Key != ConsoleKey.Escape);
   }
}
// The output from a sample console session might appear as follows:
//       Press a key, along with Alt, Ctrl, or Shift.
//       Press Esc to exit.
//       You pressed D.
//       
//       Press a key, along with Alt, Ctrl, or Shift.
//       Press Esc to exit.
//       You pressed X, along with Shift.
//       
//       Press a key, along with Alt, Ctrl, or Shift.
//       Press Esc to exit.
//       You pressed L, along with Control and Shift.
//       
//       Press a key, along with Alt, Ctrl, or Shift.
//       Press Esc to exit.
//       You pressed P, along with Alt and Control and Shift.
//       
//       Press a key, along with Alt, Ctrl, or Shift.
//       Press Esc to exit.
//       You pressed Escape. 

[8]

Windows Forms

textBox1.Text = "Bonjour tout le monde";

-> Nachricht erscheint in der TextBox.

MessageBox.Show("Bonjour tout le monde");

-> Nachricht erscheint in einem eigenen Fenster.


WPF - Windows Presentation Foundation

Formular-Layout

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="888.4" Width="533">

    <Border Padding="10">
        <StackPanel>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>

                </Grid.ColumnDefinitions>

                <Button Margin="0 0 10 0" Grid.Column="0" Content="Apply" />
                <Button Grid.Column="1" Content="Reset" />
                <Button Margin="10 0 0 0"  Grid.Column="2" Content="Refresh" />
            </Grid>

            <TextBlock Text="Pulse Properties" FontWeight="Bold" Margin="0 10 0 0"/>
            <TextBlock Text="Description" />
            <TextBox Padding="2"/>

            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="2*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>

                <StackPanel Grid.Column="0" Margin="0 0 10 0">
                    <TextBlock Text ="Status"   />
                    <TextBox Padding="2" IsReadOnly="True" Background="#eee"/>
                </StackPanel>

                <StackPanel Grid.Column="1">
                    <TextBlock Text="Revision" />
                    <TextBox Padding="2" IsReadOnly="True" Background="#eee"/>
                </StackPanel>

            </Grid>

            <TextBlock Text="Description" />
            <TextBox Padding="2"/>

            <TextBlock Text ="Part Number"   />
            <TextBox Padding="2" IsReadOnly="True" Background="#eee"/>

            <TextBlock Text="Raw Material" FontWeight="Bold" Margin="0 10 0 0"/>
            <TextBlock Text="Material" />
            <ComboBox Padding="2"/>

            <TextBlock Text="Manufacturing Info" FontWeight="Bold" Margin="0 10 0 0"/>
            <TextBlock Text="Work Centres" Margin="0 0 0 10"/>


            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>

                <StackPanel Grid.Column="0" Margin="0 0 10 0">

                    <CheckBox Content="Weld" Background="#eee"/>
                    <CheckBox Content="Assembly" Background="#eee"/>
                    <CheckBox Content="Plasma" Background="#eee"/>                    
                    <CheckBox Content="Laser" Background="#eee"/>
                    <CheckBox Content="Purchase" Background="#eee"/>
                </StackPanel>

                <StackPanel Grid.Column="1">

                    <CheckBox Content="Lathe" Background="#eee"/>
                    <CheckBox Content="Drill" Background="#eee"/>
                    <CheckBox Content="Fold" Background="#eee"/>
                    <CheckBox Content="Roll" Background="#eee"/>
                    <CheckBox Content="Saw" Background="#eee"/>
                </StackPanel>

            </Grid>

            <TextBlock Text="Length" Padding="0 10 0 0" />
            <TextBox Padding="2"/>

            <TextBlock Text ="Mass"   />
            <TextBox Padding="2" IsReadOnly="True" Background="#eee"/>

            <TextBlock Text="Finish" Margin="0 10 0 0" />
            <ComboBox Padding="2" SelectedIndex="0">
                <ComboBoxItem>Painted</ComboBoxItem>
                <ComboBoxItem>Not Painted</ComboBoxItem>
            </ComboBox>

            <TextBlock Text="Purchase Information" Margin=" 0 10 0 0"/>
                <ComboBox Padding="2" SelectedIndex="0">
                    <ComboBoxItem>Rubber</ComboBoxItem>
                    <ComboBoxItem>Not Rubber</ComboBoxItem>
                </ComboBox>

            <TextBlock Text="Supplier Name" Padding="0 10 0 0" />
            <TextBox Padding="2"/>

            <TextBlock Text="Supplier Code" Padding="0 10 0 0" />
            <TextBox Padding="2"/>

            <TextBlock Text="Additional Info" FontWeight="Bold" Margin="0 10 0 0"/>
            <TextBlock Text="Notes" />
            <TextBox Padding="2"/>

        </StackPanel>
    </Border>

</Window>


Beispiel Lotto

Grundgerüst Layout:

<Window x:Class="Aufgabe_1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Lotto" Height="383.379" Width="566.962" Background="LightYellow">
    <Grid>
        <TextBox x:Name="Z1" HorizontalAlignment="Left" Height="30" Width="30" Margin="40,40,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Background="Yellow" Padding="2" BorderThickness="2"/>
        <TextBox x:Name="Z2" HorizontalAlignment="Left" Height="30" Width="30" Margin="110,40,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Background="Yellow" Padding="2"/>
        <TextBox x:Name="Z3" HorizontalAlignment="Left" Height="30" Width="30" Margin="180,40,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Background="Yellow" Padding="2"/>
        <TextBox x:Name="Z4" HorizontalAlignment="Left" Height="30" Width="30" Margin="250,40,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Background="Yellow" Padding="2"/>
        <TextBox x:Name="Z5" HorizontalAlignment="Left" Height="30" Width="30" Margin="320,40,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Background="Yellow" Padding="2"/>
        <TextBox x:Name="Z6" HorizontalAlignment="Left" Height="30" Width="30" Margin="390,40,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Background="Yellow" Padding="2"/>
        <TextBox x:Name="SZ" HorizontalAlignment="Left" Height="30" Width="30" Margin="470,40,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Background="LightGreen" Padding="2"/>
        <Button Click="speichern" x:Name="bt" Content="Speichern" HorizontalAlignment="Left" Margin="425,104,0,0" VerticalAlignment="Top" Width="75"/>
        <TextBox x:Name="tb" HorizontalAlignment="Left" Height="27" Margin="40,141,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="460"/>
    </Grid>
</Window>

Code Behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Aufgabe_1
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        //Die beiden Arrays
        private int[] Lotto_i = new int[7];
        private string[] Lotto_s = new string[7];

        //String_Array belegen
        private void speichern(object sender, RoutedEventArgs e)
        {
            Lotto_s[0] = Z1.GetValue(TextBox.TextProperty) + "";
            Lotto_s[1] = Z2.GetValue(TextBox.TextProperty) + "";
            Lotto_s[2] = Z3.GetValue(TextBox.TextProperty) + "";
            Lotto_s[3] = Z4.GetValue(TextBox.TextProperty) + "";
            Lotto_s[4] = Z5.GetValue(TextBox.TextProperty) + "";
            Lotto_s[5] = Z6.GetValue(TextBox.TextProperty) + "";
            Lotto_s[6] = SZ.GetValue(TextBox.TextProperty) + "";

            //Umwandlung String -> Int32
            for (int i = 0; i < 7; i++)
            {
                Lotto_i[i] = Convert.ToInt32(Lotto_s[i]);
            }

            //Zeichenkette für die Ausgabe
            string Zahlen_s = "";
            for (int i = 0; i < 6; i++)
            {
                Zahlen_s += Lotto_s[i] + ", ";
            }
            Zahlen_s += "(" + Lotto_s[6] + ")";

            //Ausgabe
            tb.Text = Zahlen_s;
        }

    }
}



Datenbanken

SQL Server

https://www.microsoft.com/de-de/sql-server/sql-server-editions-express


https://www.microsoft.com/en-us/sql-server/developer-get-started/csharp/win/step/2.html


Beispiel

using System.Data.SqlClient;
using System;

namespace Bsp_1
{
    class Program
    {
        static void Main(string[] args)
        {
            SqlConnection con = null; ;
            try { 
            con = new SqlConnection("Data Source=.\\SQLEXPRESS; Initial Catalog=Northwind; Integrated Security=sspi");
            con.Open();
            Console.WriteLine("Verbindung mit der Datenbank erfolgreich!");
            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
            if (con != null)
                con.Close();            
            
            Console.ReadLine();
        }
    }
}


Je nach Pfad kann die Quelle statt Data Source=.\\SQLEXPRESS; einfach nur

Data Source=.;

heißen.



MySql-Anbindung

Vorbereitung

PROJEKT  > NuGet-Pakete verwalten > Durchsuchen > ADO.Net driver for MySQL
using MySql.Data.MySqlClient;

DB Adresse bei Xampp: 127.0.0.1;uid=root;pwd=;database=datenbankname

  • DB-Verbindung immer mit try catch
using System.Windows;

Verbindungsaufbau

using System;
using MySql.Data.MySqlClient; //<-- Neu
namespace Bsp_2
{
    class Program
    {
        static void Main(string[] args)
        {
            MySqlConnection con = null; //<-- Neu 
            try
            {
                con = new MySqlConnection("server=localhost;database=northwind;uid=root;pwd=");
                con.Open();
                Console.WriteLine("Verbindung mit der Datenbank erfolgreich!");
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            if (con != null)
                con.Close();

            Console.ReadLine();
        }
    }
}


Beispiel einer Klasse für die Datenbankverbindung:

using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;

namespace DatenbankAnbindung
{
    public class DBConnect
    {
        public MySql.Data.MySqlClient.MySqlConnection conn;
        public static bool success = false;


        public DBConnect(string connstring)
        {
            try
            {
                conn = new MySql.Data.MySqlClient.MySqlConnection();
                conn.ConnectionString = connstring; // Server, UID, PW,DB
                conn.Open();
                DBConnect.success = true;
            }
            catch(MySql.Data.MySqlClient.MySqlException ex)
            {
                DBConnect.success = false;
                MessageBox.Show(ex.Message);
            }

        }

        public MySqlDataReader Abfrage(string sqlStatement)
        {

            try
            {
                MySqlCommand cmd = new MySqlCommand(sqlStatement, conn);
                MySqlDataReader rdr = cmd.ExecuteReader();
                return rdr;
            }
            catch (Exception ex)    
            {
                MessageBox.Show(ex.Message);
                return null;
            }
        }
    }
}

Programmteil:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using MySql.Data.MySqlClient;

namespace DatenbankAnbindung
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            MySql.Data.MySqlClient.MySqlDataReader treffer= null;
        DBConnect bundesligaDB = new DBConnect("server = 127.0.0.1;uid=root;pwd=;database=bundesliga;");
        if(DBConnect.success)
            { Hauptfenster.Background = new SolidColorBrush(Colors.Green);
                // nur wenn verbunden, lohnen sich Abfragen

                textBox1.LostFocus += (Object sender, RoutedEventArgs e) =>
                {

                    treffer = bundesligaDB.Abfrage(textBox1.Text);
                
                // string sqlString = "SELECT spieler_name FROM verein, spieler WHERE verein.V_ID=spieler.Vereins_ID AND verein.name = 'FC Bayern München' ";




                if (treffer != null)
                    {
                        listBox.Items.Clear();
                        listBox.SelectionChanged += (Object sender1, SelectionChangedEventArgs e1) =>
                        {
                            MessageBox.Show(" Sie haben " + listBox.SelectedItem + " ausgewählt");
                        };
                        string itemStr = "";
                        while (treffer.Read()) // solange noch Datensätze da sind 
                        {
                            //  MessageBox.Show(treffer[3].ToString());
                            // Listbox mit den Treffern befüllen

                            // anzahl der Zellen im Treffer ermitteln
                            itemStr = "";
                            int i = treffer.FieldCount;
                            // index ++ bis anzahl 
                            for( int j= 0; j < i; j++)
                            // zellen zu string verknüpfen
                            { itemStr += treffer[j] + "\t"; }

                            listBox.Items.Add(itemStr);
                        }
                        treffer.Close();
                        label.Content = "'" + textBox1.Text + "' ergab " + listBox.Items.Count.ToString() + "Treffer";
                    }
                    else
                    {
                        Hauptfenster.Background = new SolidColorBrush(Colors.Red);
                        label.Visibility = Visibility.Hidden;
                        listBox.Visibility = Visibility.Hidden;
                    }
                };


            }



        }
    }
}


Mono

Installation in Ubuntu:

apt install apt-transport-https dirmngr
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb https://download.mono-project.com/repo/ubuntu vs-bionic main" | sudo tee /etc/apt/sources.list.d/mono-official-vs.list
sudo apt update
apt install monodevelop

[9]


Notizen

XML

XML ist eine Metasprache , mit der sich Sprachen für konkrete Anwendungssituationen entwerfen lassen. XML-Dokumente gehören meist zu exakt definierten Dokumenttypen. Man spricht auch von XML-Dialekten oder XML-Vokabularen. Diese Dokumenttypen werden speziell für die jeweiligen Bedürfnisse und Anwendungsszenarien entworfen – von der Multimediabotschaft auf dem Bildschirm eines Mobiltelefons bis zum Auftrag im internationalen Handel. Vielfach lässt sich maschinell überprüfen, ob ein Dokument einem bestimmten Typ oder Schema entspricht. Vielen Dokumenttypen sind detaillierte Anforderungen an eine Verarbeitungssoftware zugeordnet. Teialehrbuch



Diverses

Generische Programmierung = Templates [10]


thread-safe/threadsicher:

  • Threadsicherheit (englisch thread safety) ist eine Eigenschaft von Softwarekomponenten und hat eine wichtige Bedeutung in der Softwareentwicklung. Sie besagt, dass eine Komponente gleichzeitig von verschiedenen Programmbereichen mehrfach ausgeführt werden kann, ohne dass diese sich gegenseitig behindern.[11]



Code einklappen: Strg+m+o


Polymorphie: Konzept der Objektorientierung, das besagt, dass Objekte bei gleichen Methodenaufrufen unterschiedlich reagieren können.


C#-Projektdatei hat die Erweiterung: .csproj (.sln > Projektmappe)



Strukturen:

  • Einziger Unterschied zw. Struktur und Klasse: Struktur nur public, keine Zugriffsspezifizierung.

(Können auch Methoden beinhalten).)


Git, GitHub

  • Verzeichnis erstellen, Dateien erzeugen
  • Im Verzeichnis git init
  • git add -A
  • git commit -m "First commit"
  • Dateien wiederherstellen git checkout -f

git-scm.com


Quellen und Tutorials

https://www.uni-trier.de/fileadmin/urt/doku/csharp/v60/csharp6.pdf

Miles, Rob: Begin to Code with C#

Perkins, Benjamin: Beginning Visual C# 2015 Programming

Youtube-Tutorials von Jörn Loviscach

Kühnel, Andreas: Visual C# 2012

Bernhard Baltes-Götz: Einführung in das Programmieren mit C# 6

Putier, Sébastien: C#5 et Visual Studio 2013 - Les fondamentaux du langage

Hugon, Jérôme: C# 6 - Développez des applications Windows avec Visual Studio 2015

Stellman, Andrew & Jennifer Greene: C# von Kopf bis Fuß

Huber, Thomas Claudius: Windows Presentation Foundation: Das umfassende Handbuch zur WPF, aktuell zu .NET 4.6 und Visual Studio 2015

itvdn Tutorials

C# Youtube-Tutorial AngelSix

WPF Youtube-Tutorial AngelSix


| |