: Dr. Holger Schwichtenberg, Manfred Steyer
: .NET-Praxis Tipps und Tricks zu .NET und Visual Studio
: entwickler.press
: 9783868026825
: 1
: CHF 18.00
:
: Informatik
: German
: 288
: Wasserzeichen/DRM
: PC/MAC/eReader/Tablet
: PDF/ePUB
In den vergangenen Jahren haben Dr. Holger Schwichtenberg und Manfred Steyer im 'Windows Developer' regelmäßig Tipps und Tricks aus ihrem Alltag als Softwareentwickler, Berater und Trainer für .NET- und webbasierte Anwendungen veröffentlicht. Das vorliegende Buch ist eine aktualisierte und deutlich erweiterte Zusammenfassung dieser Tipps und Tricks. Es umfasst sowohl das .NET Framework und seine zahlreichen Teilbibliotheken als auch die beliebte JavaScript-Bibliothek AngularJS sowie die Entwicklungsumgebung Visual Studio und ergänzende Werkzeuge. In zahlreichen Kurzkapiteln zeigen die Autoren praxisnahe und anschauliche Anleitungen und Kniffe, mit denen die Leser ihre eigenen .NET- und Visual-Studio-Anwendungen optimieren und erweitern können.

Manfred Steyer arbeitet als Trainer und Berater bei www.IT-Visions.at. Daneben ist er für den Fachbereich Software Engineering der Studienrichtung IT und Wirtschaftsinformatik an der FH CAMPUS 02 in Graz verantwortlich. Er schreibt regelmäßig für diverse Fachzeitschriften und Verlage und spricht auf Fachkonferenzen. 2015 wurde er als Microsoft Most Valuable Professional ausgezeichnet. Weblog: www.softwarearchitekt.at Dr. Holger Schwichtenberg (alias 'DOTNET-DOKTOR') ist Leiter des .NET-Expertennetzwerks www.IT-Visions.de und beim Softwareentwicklungsdienstlei ter 5Minds IT-Solutions GmbH& Co. KG. Er gehört durch seine Auftritte auf nationalen und internationalen Fachkonferenzen sowie zahlreiche Veröffentlichungen zu den bekanntesten .NET-Experten in Deutschland und ist als Microsoft Most Valuable Professional ausgezeichnet. Weblog: www.dotnet-doktor.de.

2 .NET Framework Class Library (FCL)

2.1 ExpandoObject

Für Fälle, in denen lediglich ein dynamisches Objekt, welches das freie Definieren von Eigenschaften und Methoden erlaubt, benötigt wird, kann seit .NET 4.0 auf die KlasseExpandoObject zurückgegriffen werden. Listing 2.1 demonstriert die Verwendung dieser Klasse. Zunächst werden dem Objekt die EigenschaftenFirstName undLastName hinzugefügt, anschließend bekommt es eine MethodeDoStuff, die als Lambdaausdruck übergeben wird, spendiert. Danach werden die beiden Eigenschaften wieder ausgelesen und die Methode wird aufgerufen.

dynamic whatever = new ExpandoObject();
whatever.FirstName ="Max";
whatever.LastName ="Mustermann";
whatever.DoStuff = new Action(() => Console.WriteLine("Hello World!"));

Console.WriteLine(whatever.FirstName +"" + whatever.LastName);
whatever.DoStuff();

Listing 2.1

2.2 Prüfung auf 64 Bit

Mit zwei Eigenschaften kann ab .NET 4.0 geprüft werden, ob die aktuelle Applikation in einem 64-Bit-Prozess läuft und ob es sich bei dem aktuellen Betriebssystem um ein 64-Bit-Betriebssystem handelt. Für Ersteres stehtIs64BitProcess zur Verfügung, für LetzteresIs64BitOperatingSystem. Ein Beispiel, das die Werte dieser beiden booleschen Eigenschaften auf der Konsole ausgibt, findet sich in Listing 2.2.

Console.WriteLine("Is64BitProcess:" + Environment.Is64BitProcess);
Console.WriteLine("Is64BitOperatingSystem :" + Environment.Is64BitOperatingSystem);

Listing 2.2

2.3 BigInteger

Für jene Fälle, in denen mit ganzzahligen Werten beliebiger Größe gerechnet werden soll, bietet .NET seit Version 4.0 eine neue Struktur namensBigInteger (System.Numeric.BigInteger) an. Damit Instanzen vonBigInteger ähnlich wie herkömmliche Integer-Werte behandelt werden können, wurden sämtliche arithmetischen Operatoren sowie Bit-, Vergleichs- und Zuweisungsoperatoren überladen. Ein Beispiel für die Verwendung dieses neuen Typs ist in Listing 2.3 zu sehen. Dabei fällt auf, dass einemBigInteger primitive Integer-Werte direkt zugewiesen werden können, ohne dafür eine eigene Instanz vonBigInteger erzeugen zu müssen. Einige Methoden, die für primitive Datentypen in der KlasseMath untergebracht wurden, finden sich als statische Methoden direkt in der KlasseBigInteger wieder. Als Beispiele solcher Methoden seien an dieser StellePow (Potenz),Abs (Absolutwert) sowieLog (Logarithmus) genannt.

BigInteger bigInt1;
BigInteger bigInt2;

bigInt1 = long.MaxValue;
bigInt1 = bigInt1 * bigInt1;

bigInt2 = bigInt1;
bigInt2 = bigInt2 + 1;

Console.WriteLine(bigInt2);

Listing 2.3

2.4 Standortermittlung

Beim Einsatz von Windows 7 besteht die Möglichkeit, unter Verwendung von Sensoren den aktuellen Standort herauszufinden. Wer einen solchen Sensor nicht sein Eigen nennt, kann softwarebasierte Varianten im Internet zum Download finden. Nach der Installation muss der Sensor in der Systemsteuerung unterOrtung und andere Sensoren aktiviert werden.

Sensoren dieser Art können ab .NET 4.0 angesprochen werden, wie in Listing 2.4 demonstriert. Dieses Beispiel ermittelt über eine Instanz vonGeoCoordinateWatcher die aktuellen Koordinaten (Längengrad, Breitengrad) und versucht mit diesen unter Verwendung einesCivicAddressResolver die dazugehörige zivile Adresse herauszufinden. Die MethodeTryStart startet die Verwendung des Sensors. Das erste Argument gibt an, ob der Dialog, der den Benutzer um Erlaubnis zur Verwendung der aktuellen Position bittet, unterdrückt werden soll. Wird dieser Dialog unterdrückt, muss bereits die Verwendung des Sensors durch den Benutzer bewilligt worden sein, damit der aktuelle Standort ermittelt werden kann. Das zweite Argument gibt an, wie viel Zeit in die Ermittlung der aktuellen Position maximal investiert werden darf. Der boolesche Rückgabewert gibt Aufschluss über den Erfolg der Standortermittlung. Im betrachteten Beispiel werden die ermittelten Geodaten sofort verwendet. Um über Standortänderungen informiert zu werden, kann zusätzlich das EreignisPositionChanged der KlasseGeoCoordinateWatcher verwendet werden. Über die EigenschaftMovementThreshold kann dabei in Metern angegeben werden, nach welcher Distanz dieses Ereignis aufgerufen werden soll.

GeoCoordinateWatcher watcher = new
GeoCoordinateWatcher(GeoPositionAccuracy.Default);
bool started = watcher.TryStart(false, TimeSpan.FromMilliseconds(1000));
if (!started) Console.WriteLine("GeoCoordinateWatcher timed out on start.");
CivicAddressResolver resolver = new CivicAddressResolver();
if (!watcher.Position.Location.IsUnknown)
{
CivicAddress address = resolver.ResolveAddress(watcher.Position.Location);
if (!address.IsUnknown)
{
Console.WriteLine("Country: {0}, Zip: {1}, City: {2}",
address.CountryRegion,
address.PostalCode,
address.City);
}
}

Listing 2.4

2.5 Interprozesskommunikation mit Memory-mapped Files

Memory-mapped Files erlauben das Bereitstellen von Informationen über den Hauptspeicher und werden gerne zur Interprozesskommunikation eingesetzt. Listing 2.5 zeigt, wie ein solches Memory-mapped File erzeugt und beschrieben werden kann. Zunächst wird ein Memory-mapped File mit dem NamensomeMemoryMappedFile und einer maximalen Größe von 1 000 Bytes erzeugt. Zum Zugriff auf dieses File wird anschließend mittelsCreateViewStream ein Stream erzeugt, der den Zugriff auf einen Ausschnitt (View) des Memory-mapped Files gewährt. Da an dieser Stelle keine weiteren Parameter angegeben werden, erstreckt sich dieser Ausschnitt auf das gesamte File. Überladungen dieser Methode erlauben jedoch die Angabe eines Offsets sowie einer Länge für den zu bearbeitenden Ausschnitt. Darüber hinaus existiert auch eine Überladung, die zusätzlich die Angabe von Zugriffsberechtigungen erlaubt. Anschließend wird über einenBinaryWriter der StringHello World in den Stream geschrieben und die Datei geschlossen. Im zweiten Teil von Listing 2.5 wird das Memory-mapped File erneut geöffnet und gelesen.

using (var file = MemoryMappedFile.CreateNew("someMemoryMappedFile", 1000))
{
using (var stream = file.CreateViewStream())
{
var writer = new BinaryWriter(stream);
writer.Write("Hello World!");
}
}
[...]
using (var file = MemoryMappedFile.OpenExisting("someMemoryMappedFile"))
{
using (var stream = file.CreateViewStream()) {
var reader = new BinaryReader(stream);
Console.WriteLine(reader.ReadString());
}
}

Listing 2.5

2.6 Auf Textdateien mittels LINQ zugreifen

Als Alternative zuFile.ReadAllLines wird ab .NET Version 4.0 eine MethodeReadLines bereitgestellt, die anstatt eines String-Arrays einIEnumerable<string> zurückliefert. Bei einer Iteration diesesIEnumer­able werden die Zeilen nach und nach geladen. Analog dazu stehen mitAppendAllLines undWriteAllLines Methoden zur Verfügung, welche die Zeilen aus einemIEnumerable<string> an eine Datei anhängen bzw. eine Datei mit diesen Zeilen erstellen oder überschreiben. In dieselbe Kerbe schlagen drei neue Methoden der KlasseDirectoryInfo:EnumerateFiles,EnumerateDirectories undEnumerateFileSystemInfos. Diese Methoden liefern einIEnumerable mit den Dateien und/oder Verzeichnissen, die sich innerhalb des jeweiligen Ordners befinden.

Da LINQ auf den Möglichkeiten vonIEnumerable basiert, erlauben diese neuen Methoden ein einfaches und elegantes Formulieren von Abfragen, welche sich auf Dateien und Dateiinhalte beziehen. Die LINQ-Abfrage in Listing 2.6 ermittelt mit diesen Methoden beispielsweise jene Zeilen aus sämtlichen CSV-Dateien des aktuellen Ordners, bei denen sich in der ersten Spalte der Wert 1 wiederfindet. Das Ergebnis dieser Abfrage – einIEnumerable<string> – wird anschließend an die zuvor erwähnte MethodeWriteAllLines übergeben, um die gefundenen Zeilen in der Dateiresult.txt zu hinterlegen.

DirectoryInfo dir = new DirectoryInfo(".");

var info =
from file in Directory.EnumerateFiles(".","*.csv")
from line in File.ReadLines(file)
where line.Split(';')[0] =="1"
select file +":" + line;

File.WriteAllLines("result.txt", info);

Listing 2.6

2.7 Erweiterungsmethode „String.Truncate()“

In Visual Basic ist dieLeft()-Funktion ein wichtiges Instrument, um die Länge einer Zeichenkette zu begrenzen, zum Beispiel vor der Übergabe an ein Datenbankfeld begrenzter Länge. Überstehende Zeichen werden dabei abgeschnitten. In C# gibt es diese Funktion nicht, man muss immer mitString.SubString() arbeiten. Aber Achtung: Wenn die...

Inhaltsverzeichnis5
Vorwort11
1CLR und Sprach­syntax (C#/Visual Basic)13
1.1.NET Framework 4.5.1 und 4.5.2 erkennen13
1.2.NET Framework 4.6 erkennen15
1.3Den Large Object Heap komprimieren16
1.4C# 6.0 und Visual Basic 14 in älteren .NET-Projekten nutzen18
1.5Einsatz der dynamischen Typisierung in C#19
1.6Kovarianz (Covariance) in C#22
1.7Kontravarianz (Contravariance) in C#24
1.8Ko- und Kontravarianz in Visual Basic .NET26
1.9Null-conditional Operator in C# 6.0 und Visual Basic 1426
1.9.1Motivation26
1.9.2Der neue Null-conditional Operator28
1.9.3Null-conditional Operator und Ereignisse28
1.9.4Null-conditional Operator und Indexer29
1.10String-Interpolation in C# 6.0 und Visual Basic 1429
1.11Operator „nameof“ in C# 6.0 und Visual Basic 1430
1.12Exception-Filter in C# 6.032
2.NET Framework Class Library (FCL)35
2.1ExpandoObject35
2.2Prüfung auf 64 Bit35
2.3BigInteger36
2.4Standortermittlung37
2.5Interprozesskommunikation mit Memory-mapped Files38
2.6Auf Textdateien mittels LINQ zugreifen39
2.7Erweiterungsmethode „String.Truncate()“40
2.8Erweiterungsmethoden „String.ToDateTime()“, „ToInt32()“, „ToDecimal()“41
2.9Eine einfache Objektausgabefunktion für alle .NET-Objekte45
2.10Zugriff auf COM-Bibliotheken ohne Primary Interop Assemblies (NoPIA)50
2.11Übertragen von Daten zwischen Streams50
2.12Enums und Bitmasken51
2.13Caching mit „System.Runtime.Caching“52
2.14Caching-Datenmenge begrenzen53
2.15Caching ganz einfach per Cachemanager55
2.16Verzögertes Instanziieren mit Lazy63
2.17Tuples65
2.18SortedSet67
2.19Observer68
2.20API-basierte Konfiguration in MEF 271
2.21„InnerException“-Ausgabe ohne Stacktrace75
2.22Dateien mit ZIP komprimieren77
2.23Den angemeldeten Benutzer ermitteln80
2.24Eigenschaften eines Benutzerkontos ändern82
2.25Benutzerinformationen auslesen85
2.26 Ein neues Benutzerkonto anlegen89
3ADO.NET und Entity Framework93
3.1Abgebrochene Datenverbindung automatisch neu aufbauen93
3.2Ladeoptimierung durch Abfragen ohne Änderungsverfolgung (No-Tracking Queries)97
3.3Objekte löschen, ohne sie vorher zu laden100
3.4Setzen des Concurrency Mode für alle Spalten in der EDMX-Datei101
3.5Setzen des Concurrency Mode für alle Spalten bei Code-based Modeling103
3.6Entity Framework Logging108
3.7Entity Framework Profiling113
3.8Speicheroperationen optimieren117
3.9Massenoperationen mit Entity Framework121
3.10UPDATE und DELETE per Lambdaausdruck122
4Windows Management Instrumentation (WMI)125
4.1Liste der verfügbaren Laufwerke125
4.2Füllstand der Laufwerke auflisten127
4.3Computer neustarten128
4.4Laufwerksname ändern130
4.5Computer umbenennen131
4.6Hardware auflisten132
5ASP.NET Web Forms und MVC135
5.1C# 6 und Visual Basic 14 in ASP.NET-Webseiten verwenden135
5.2Tipps zur Leistungssteigerung in ­ASP.?NET Web Forms136
5.3Leistungssteigerung durch Seiten-Caching137
5.3.1Caching-Profile in der „web.config“-Datei141
5.3.2Caching einzelner Steuerelemente141
5.4Asynchrone Controller in ASP.NET MVC143
5.5Minification und Bundling144
5.6In ASP.NET 4.x wie in ASP.NET 3.5 rendern146
5.7HTML Encoded Code Expressions in ASP NET 4.0147
5.8Vorlagen für Felder und Models in ASP.?NET MVC149
5.9Razor Helper für Views ASP.NET MVC151
5.10Views für mobile Anwendungen in ASP.?NET MVC152
5.11ASP.NET-MVC-Modelle mit jQuery Validate validieren154
5.12Sprach- und Ländereinstellungen für ASP NET MVC festlegen157
5.13Bei ASP.NET MVC 4 Seiten über Google, Facebook, Twitter und Co. anmelden159
5.14Pipelinemodule für Querschnitts­funktionen in ASP.NET SignalR162
6Windows Communica­tion Foundation (WCF)165
6.1Kerberos vs. NTLM165
6.2Antwortformat bei REST-Services dynamisch festlegen166
6.3Bandbreite mit „EmitDefaultValue=false“ sparen167
6.4Lebensdauer von Sessions beeinflussen169
6.5Fehlerdetails bei WCF Services anzeigen170
6.6Hilfeseite für REST-Services172
6.7Anpassung der Serialisierung von String-Listen mit „CollectionDataContractAttribute“172
6.8Leistungsindikatoren für WCF-Services174
6.9Einfluss auf den Mengentyp im Proxy175
6.10Port Sharing bei TCP-basierten Services176
6.11UDP Binding und Multicasts in WCF 4.5178
6.12Erweiterbare Datenverträge180
6.13Programmatische Impersonation181
6.14Kompression bei binärer Kodierung in WCF 4.5181
6.15Deklarative Im