.NET Blog   ·   .NET Casts   ·   .NET GUI Foren   ·   .NET BlogBook   ·   WPF Blogger   ·   visual studio one   ·   ASP.NET professional

  • ACHTUNG - NEUES BLOG

    Ab sofort steht unter http://devtyr.norberteder.com mein neues Blog zur Verfügung. Dieses Blog wird nicht weiter betreut, bleibt aber erhalten. Neue Eintr%auml;ge erfolgen nur mehr im neuen Blog. Kommentare werden ebenfalls nicht mehr behandelt. Wer weiterhin meinen Einträgen und Aktivitäten folgen möchte, möge bitte RSS-Feeds, Verlinkungen etc. an die neue Location anpassen.
Download .NET Essentials Installer
Trickkiste

System.IO.Compression - Hilfreich oder doch ein Scherz?

07.06.06 - Base Framework
Beitrag von Norbert Eder
 Unter dem .NET Framework 2.0 gibt es ja den System.IO.Compression-Namespace. Dieser beinhält Klassen um Dateien zu zippen. Vorgangsweise sieht so aus, dass Daten in einen Stream geschrieben werden (beispielsweise einem GZipStream). Dieser zippt danach die Daten, welche in weiterer Folge in einer Zip-Datei abgelegt werden können.

Dies funktioniert wenn man eine einzelne Datei zippen möchte. Was ist, will ein gesamtes Verzeichnis gepackt werden? Gute Frage. Bis dato konnte ich noch keine Art Zip-Container finden. Dies bedeutet, man muss sich die einzelnen Positionen der Dateien innerhalb des Streams merken bzw. an einer Stelle vermerken, um diese wieder entpacken zu können. Ein handelsübliches Zip-Programm ist damit natürlich überfordert. Dies läßt die Frage offen, ob damit proprietäre Formate unterstützt werden sollen ...

Fazit
Ich hätte mir unter diesem Namespace doch wesentlich mehr vorgestellt. So ist er für mich nicht wirklich zu gebrauchen. Schade drum.

ZUSATZ
Für diejenigen, die nicht in die Kommentare sehen, hier ein Zusatz. Jay hat einen Link gepostet, der genau dieses Manko behebt:
.NET System.IO.Compression and zip files

  4 Kommentare - 1045 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


.NET 2.0: ComboBox und AutoComplete

22.05.06 - Base Framework
Beitrag von Norbert Eder
 Unter .NET 2.0 gibt es eine sehr einfache Möglichkeit, der ComboBox eine AutoComplete-Funktion bzw. eine Vorschlags-Funktion zu verpassen.

Dazu einfach folgende Schritte ausführen:

1. AutoCompleteCustomSource setzen (zusätzlich zur normalen DataSource)
2. AutoCompleteMode auf Suggest stellen
3. AutoCompleteSource auf ListItems stellen

Fertig ist die Hexerei und der User freut sich über die verbesserte Usability. Statt Suggest (Punkt 2) gibt es auch noch weitere Möglichkeiten um eventuell eigene Einträge anzuhängen etc. Einfach mal ausprobieren.

  1 Kommentar - 1577 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


IronPython 1.0 Beta 6 verfügbar

28.04.06 - Base Framework
Beitrag von Norbert Eder
 Wer schon immer gerne über den eigenen Tellerrand geblickt hat, für den steht die Beta 6 von IronPython 1.0 [1] zur Verfügung. Dabei handelt es sich um die .NET Implementierung von Python.

Zwingend notwendig ist das .NET Framework 2.0 [2].

[1] Download IronPython 1.0 Beta 6
[2] Microsoft .NET Framework Version 2.0 Redistributable Package (x86)

Weitere Informationen

[3] IronPython Home
[4] IronPython: A fast Python implementation for .NET and Mono
[5] Python + .NET = IronPython

  1 Kommentar - 685 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


C# vs. VB.NET

08.04.06 - Base Framework
Beitrag von Norbert Eder
 Ein Thema das wohl nie enden wird. Was ist denn nun besser? C# oder VB.NET? Hier eine kleine Linksammlung zu diesem Thema, damit sich jeder selbst ein Bild davon machen kann:

[1] What are the advantages of C# over VB.NET and vice versa?
[2] VB.NET vs C#: The Great .NET Language Debate
[3] Top 10 reasons C# is better than VB.NET
[4] Complete Comparison for VB.NET and C#
[5] Yet again: VB vs C#
[6] Und VB .NET hat doch einen Sinn

Ich könnte die Liste jetzt noch weiter fortsetzen, aber ich denke diese Links sollten für eine Entscheidungsfindung reichen.
  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


C#-Beginner: Exception-Handling unter C#

02.03.06 - .NET, Base Framework
Beitrag von Norbert Eder
 Das Thema Exception-Behandlung scheint bei vielen .NET Programmierern noch nicht richtig angekommen zu sein. Immer wieder finden sich in diversen Beispielen und Fragen traurige Konstrukte, die hauptsächlich negative Erscheinungen zu Tage fördern. Also Beispiel sei hier ein neulich gesichteter Code gezeigt werden (nicht kopieren!!!!!):


try
{
StreamReader sr = new StreamReader("path");
string text = sr.ReadToEnd();
sr.Close();
}
catch (Exception ex) {}


Das Ergebnis? Nun, ist die Datei nicht vorhanden wird eine Exception geworfen und auch abgefangen, aber es passiert damit nichts. Es erfolgt weder eine Meldung an den User, noch ein Log-Eintrag, um etwaige Fehler zu einem späteren Zeitpunkt nachvollziehen zu können. Ein weiterer Effekt ist, dass beim "Testen" durch den Entwickler "alles funktioniert" - was natürlich nicht stimmt.

Nun gut, aber wie soll das Exception Handling dann wirklich umgesetzt werden? Ganz einfach. Der grundlegende try-catch-Block sieht so aus:


try {
// Implementierung
} catch (IOException ex) {
// Fehlerbehandlung für IO-Fehler
} catch (Exception ex) {
// Fehlerbehandlung für andere Fehler
} finally {
// Abschlussarbeiten
}


Hier noch eine genaue Beschreibung:

try: Im try-Teil des gesamten Blockes erfolgt die Implementierung der tatsächlichen Funktion.

catch: Hier ist die Fehlerbehandlung zu implementieren. Dies kann realisiert werden, indem die Fehlermeldungen bzw. zusätzliche Einträge in eine Log-Datei geschrieben werden oder eine User-Interaktion verlangt wird. Wie oben gezeigt, können mehrere Exceptions gezielt abgefangen und behandelt werden. In der MSDN finden sich zu allen Methoden auch Angaben darüber, welche Exceptions geworfen werden. Prinzipiell ist mit diesen Exceptions zu arbeiten und nicht direkt mit Exception selbst.

finally: Dieser Teil des Blockes wird in jedem Fall ausgeführt, also sowohl nach erfolgreichem Durchlauf des try-Teiles, als auch im Falle eines Fehlers. Dadurch bietet es sich an, im finally-Block Aufräumarbeiten durchzuführen. Dies kann beispielsweise das Schließen einer Datenbank-Verbindung sein.

Beim catch-Block muss nicht zwingend ein Typ angegeben werden. Ist dies nicht der Fall, dann werden sämtliche Exceptions behandelt. Von dieser Schreibweise würde ich jedoch eher abraten:


try {

} catch {

}


Des weiteren sollten Exception nicht für die Ablaufsteuerung einer Anwendung verwendet werden. Darunter wird verstanden, dass gezielt auf Exceptions abgefragt wird, um aufgrund des Exception-Typs zu entscheiden, welcher weitere Code anschließend ausgeführt wird. Exceptions sind sehr "teuer". Dies bedeutet, dass dadurch viele Ressourcen verbraucht werden. Daher sind Exceptions auch als solche zu behandeln.

Natürlich besteht auch die Möglichkeit eigene Exceptions zu implementieren. Dies macht vor allem bei der Entwicklung von größeren Frameworks (die auch von anderen Entwicklern benutzt werden) Sinn. Folgendes Beispiel soll eine eigene Exception verdeutlichen:


using System;
class MyException : ApplicationException
{
public MyException(string str)
{
Console.WriteLine(str);
}
}


Wie zu erkennen ist, ist von der Basisklasse ApplicationException abzuleiten. Der Konstruktor erhält einen Parameter und damit ist die einfachste Variante einer benutzerdefinierten Exception fertig. Weitere Möglichkeiten können aus der MSDN bezogen werden.

Zum Schluss möchte ich noch kurz ansprechen, wie der Programmierer selbst Exceptions werfen kann. Dies wird mittels des Schlüsselwortes throw getan:


throw new MyException("Eine benutzerdefinierte Exception ist aufgetreten");


Eine so geworfene Exception muss natürlich auch entsprechend behandelt werden.

Referenzen und weiterführende Artikel:
[1] Exception Management Architecture Guide
[2] Exception Class

  3 Kommentare - 1662 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


[Tutorial] Unit-Tests mit Visual Studio .NET

14.02.06 - Base Framework
Beitrag von Norbert Eder
 

Unit-Tests unter Visual Studio .NET



Inhalt

1. Einführung und Ausblick
2. Begriffserklärung
3. Notwendige Tools
4. Installation
5. Vorarbeiten
6. Ein konkretes Beispiel
7. Konklusio


1. Einführung und Ausblick



Bei fast allen Fragestellungen in diversen Foren gibt es Fragen zu Fehlern, die auf dreierlei Arten auftreten:

1. Mangelndes studieren der zur Verfügung stehenden Quellen. Dies inkludiert nicht nur diverse Artikel, die es im Internet zu finden gibt (ein Beispiel hier wäre die MSDN), sondern auch in Form von Büchern oder den zu den verwendeten Werkzeugen mitgelieferten Ressourcen.

2. Fehlendes Verständnis und Wissen rund um den Debugger. Immer wieder muss ich feststellen, dass der Debugger wenig bis gar keine Beachtung findet, obwohl sich durch ihn das wohl beste "Werkzeug" überhaupt offenbart. Auf schnelle Art und Weise können nicht nur Syntax-Fehler gefunden werden, nein, es können auch Variableninhalte abgefragt werden, Objektinformationen bezogen und sogar Abfragekommandos an den Compiler übergeben werden.

3. Ignoranz von Unit-Tests. Die Verwendung von Unit-Tests wird in vielen Fällen nur Profis zugetraut und aus diesem Grunde wird ihnen kaum Beachtung geschenkt - oder aber, einfach das fehlende Wissen um diese Möglichkeit.

Dieser Artikel soll zeigen, dass selbst Programmier-Anfänger sehr einfach Unit-Tests verwenden können.

2. Begriffserklärung



Bevor wir aber tiefer in die Materie einsteigen, muss der Begriff Unit-Test erklärt werden.

Durch Unit-Tests ist es möglich, Testklassen zu schaffen, die automatisiert andere, vorhandene Klassen testen.

So werden pro Testklasse folgende Dinge der zu testenden Klasse angegeben und getestet:

* alle Methoden
* alle Überladungen
* in allen erdenklichen Übergabeparametern (auch sinnlosen Varianten)

Vor allem die "sinnlosen Varianten" sind für die Tests sehr wertvoll: Dadurch werden Überläufe, und vor allem auch Fehleingaben durch User (diese passieren immer und überall) mit in den Test einbezogen und im Fehlerfalle kann dies bevor das Produkt den User erreicht nachgebessert werden.

Der Sinn hinter solchen Tests ist der, dass wie oben beschrieben, problematische Parameterübergaben im Fehlerfalle behandelt werden (da auf das Testergebnis entsprechend zu reagieren ist). Da eine Software laufend weiterentwickelt wird, werden auch ständig an allen erdenklichen Stellen Änderungen vorgenommen. Dadurch ist es in manchen Fällen schwer zu sagen, ob eine andere Stelle noch korrekt funktioniert. Durch diese Unit-Tests kann dies einfach festgestellt werden. Dazu sind nach der durchgeführten Änderung die Tests auszuführen und wenige Sekunden bis Minuten später (Abhängig von der Projektgröße) hat der Programmierer Gewissheit.

3. Notwendige Tools



Zu Beginn muss natürlich geklärt werden, welche Tools notwendig sind, um Unit-Tests unter dem Visual Studio verwenden zu können.

Aus meiner Erfahrung haben sich folgende Produkte als äußerst hilfreich erwiesen:

* TestDriven.NET [1]
* NUnit [2]

Bei TestDriven.NET handelt es sich um Unit-Testing Add-In für Visual Studio, welches mit unterschiedlichsten Unit-Testing-Tools zusammenarbeiten kann. Zu erwähnen wären hier NUnit, MbUnit und csUnit.

Bei NUnit handelt es sich um ein Test-Unit Framework, mit dessen Hilfe Unit-Tests durchgeführt werden können.

4. Installation



An diesem Punkt möchte ich nur an die entsprechenden Installations-Hinweise der Hersteller verweisen:

NUnit: http://www.nunit.org/index.php?p=installation&r=2.2.6

Bei TestDriven.NET ist lediglich die Installationsdatei zu starten. Daraufhin wird das Add-In im Visual Studio registriert und steht fortan zur Verfügung.

5. Vorabeiten



Um nun für ein neues oder bereits bestehendes Projekt Unit-Tests anzuwenden, sind kleine Vorabeiten notwendig.

Idalerweise empfiehlt es sich, Unit-Tests in ein eigenes Projekt auszulagern. Dieses Projekt muss natürlich Teil der Visual Studio Solution sein.

Nach dem Anlegen dieses Projektes, ist eine Referenz auf die nunit.framework.dll zu setzen. Ist dies geschehen, kann es mit einem konkreten Beispiel weitergehen.

6. Ein konkretes Beispiel



Gehen wir davon aus, dass unser Projekt einen Logger besitzt. Dieser hat die Aufgabe, allfällige Fehler in eine Logdatei zu schreiben. Natürlich muss dieser getestet werden, ob er auch den an ihn gestellten Anforderungen gerecht wird.

Dazu erstellen wir eine TestKlasse LoggerTest. Die neue Klasse muss zusätzlich mit dem Attribut [TestFixture] markiert werden. Danach erstellen wir die einzelnen Methoden, welche die einzelnen Tests darstellen. Beispielsweise könnte dies folgendermaßen aussehen:


public void LoggerLog()
{
try
{
Logger log = new Logger();
log.LogPath = @"C:temptemp.log";
log.Log("test");
Assert.IsTrue(true);
}
catch (Exception ex)
{
Assert.Fail(ex.Message);
}
}



Wie an diesem Beispiel zu sehen ist, müssen die zu testenden Methoden mit dem Attribut [Test] versehen werden.

Mit einem Rechtsklick auf die entsprechende Datei kann nun mittels "Run Test(s)" der Test gestartet werden. Wird dieser Befehl auf das Projekt angewandt, werden alle darin enthaltenen Tests gestartet.

Nach dem Durchlauf der Tests erscheint im Ausgabe-Fenster die Angabe, welche Tests durchgelaufen (also erfolgreich waren) und welche nicht.

Wann ein Test als erfolgreich und wann als nicht erfolgreich gilt, muss vom Entwickler selbst angegeben werden. Im Falle einer Exception darf der Test natürlich nicht als erfolgreich angeführt sein. Wurden alle Punkte durchlaufen und stimmt das Ergebnis, kann der Test als erfolgreich markiert werden.

Dafür zuständig ist die Klasse Assert. Diese hat einige Methoden, die für diese Aufgabe sehr hilfreich sind:

Assert.Fail: Hier ist ein String zu übergeben, der angibt, um welchen Fehler es sich handelt. Dies kann die Message-Eigenschaft einer Exception sein, oder auch ein selbst definierter String, um mitzuteilen wo bei was ein Fehler aufgetreten ist.

Assert.IsTrue: Hier werden normalerweise Vergleiche angegeben. Beispielsweise das Ergebnis der Methode und das Ergebnis, welches die Methode liefern sollte. Sind beide Ergebnisse ident, ist der Test durchgelaufen, andernfalls nicht.

Assert.IsFalse: Dies funktioniert wie Assert.IsTrue, nur in die entgegengesetzte Richtung.

7. Konklusio



Dieses kleine Tutorial lieferte einen kurzen Einblick in das Thema Unit-Tests unter Visual Studio und zeigt durchaus, dass sich dahinter keine komplizierten Abläufe verbergen. Stöbert man ein wenig in den angegebenen Internet-Ressourcen herum, können sehr schnell gute und hilfreiche Ergebnisse erreicht werden.

Sollten dennoch Fragen zu dem Thema entstehen - welche durch die angegebenen Ressourcen nicht abgedeckt werden können, kann der werte Leser mich unter csharp@gmx.at erreichen.


Referenzen

[1] http://www.testdriven.net
[2] http://www.nunit.org

  3 Kommentare - 3629 mal angesehen   |  2 Trackbacks   |  Permalink  |  Trackback-URL


Application Blocks für das .NET Framework 2.0

06.02.06 - Base Framework
Beitrag von Norbert Eder
 Wer sich für Enterprise-Design interessiert, dem werden einige nette Hilfsmittel von Microsoft zur Verfügung gestellt.

In der Enterprise Library for .NET Framework 2.0 finden sich ein paar Application-Blocks als Sourcecode und dürfen auch entsprechend verwendet werden.

Ein Blick lohnt sich auf alle Fälle für Application-Designer und solche, die es werden wollen.

  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


C#: Methode mit Parameter via ThreadStart aufrufen

29.01.06 - .NET, Base Framework
Beitrag von Norbert Eder
 Im heutigen Beitrag zum Thema "C# Beginner" möchte ich ein Beispiel zeigen, wie mittels ThreadStart eine Methode inkl. Parameter aufgerufen werden kann.

Dazu ist einfach die entsprechende Methode in eine eigene Klasse mit den notwendigen Properties auszulagern:

private class TestClass {

private string parameter = null;

public string Parameter {
get { return this.parameter; }
set { this.parameter = value; }
}

public void Start() {
// code goes here
}

}

In der ursprünglichen Klasse wird der Thread wie folgt gestartet:

TestClass tc = new TestClass();
tc.Parameter = "test";
Thread t = new Thread(new ThreadStart(tc.Start)).Start();

Das wars dann auch schon wieder.

  1 Kommentar - 2827 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Strings unter .NET

22.01.06 - Base Framework
Beitrag von Norbert Eder
 Dieser Eintrag soll aufführen, wie Strings unter .NET intern behandelt werden.

Strings sind unter .NET immutable. Das bedeutet, dass sie nicht veränderbar sind.

Man nehme das folgende Beispiel:

string muh = "muh";
muh += "kuh";

Hier sieht das ganze so aus, dass zuerst ein String-Objekt mit dem Value "muh" gebildet wird. Möchten wir an "muh" den String "kuh" anhängen passiert folgendes:

Es wird ein neues String-Objekt am Heap erzeugt. Die Größte (Länge) des String-Objektes beträgt muh.Length + "kuh".Length. Nun wird das Ergebnis aus "muh" + "kuh" in das neue String-Objekt kopiert. Das alte String-Objekt muh wird nun für die Gargabe Collection freigegeben.

Was sagt uns das jetzt? Es sollte wenn möglich der StringBuilder verwendet werden. Dieser zahlt sich aber erst nach einigen String-Operationen aus, da die Instanzierung des StringBuilders natürlich auch Kosten verursacht. Ich nehme hier als Richtwert 5 bis 7 String-Operationen.

  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Wie die benötigten Rechte einer Assembly feststellen?

10.01.06 - Base Framework
Beitrag von Norbert Eder
 Mir hat sich die Frage gestellt, wie man möglichst einfach die für die Ausführung einer Assembly notwendigen Rechte herausfinden kann. Unter .NET 2.0 ist dies recht einfach durch das Tool permcalc möglich.

Aufruf

permcalc -Show norberteder.com.lib.dll

Ausgabe

Folgende XML-Datei wird erstellt:


<?xml version="1.0"?>
<Assembly>
<Namespace Name="norberteder">
<Namespace Name="com">
<Namespace Name="lib">
<Namespace Name="globalization">
<Type Name="Translator">
<Method Sig="instance string get_DefaultLanguage()" />
<Method Sig="instance void set_DefaultLanguage(string )" />
<Method Sig="instance string get_CurrentLanguage()" />
<Method Sig="instance void set_CurrentLanguage(string )" />
<Method Sig="instance void RegisterGlobalizationFile(string )" />
<Method Sig="instance void Initialize()">
<Demand>
<PermissionSet version="1" class="System.Security.PermissionSet">
<IPermission version="1" class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" PathDiscovery="*AllFiles*" />
</PermissionSet>
</Demand>
<Sandbox>
<PermissionSet version="1" class="System.Security.PermissionSet">
<IPermission version="1" class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" PathDiscovery="*AllFiles*" />
</PermissionSet>
</Sandbox>
</Method>
<Method Sig="instance string Translate(struct TranslatorSelector , string )" />
<Method Sig="class Translator get_GetTranslator()" />
<Method Sig="void .cctor()" />
</Type>
<Type Name="TranslatorException">
<Method Sig="instance void .ctor(string )" />
<Method Sig="instance void .ctor(string , class Exception )" />
</Type>
</Namespace>
</Namespace>
</Namespace>
</Namespace>
</Assembly>

Aus diesen Informationen kann genau ausgelesen bzw. abgefragt werden, welche Berechtigungen mind. gesetzt werden müssen um alle Funktionen nutzen zu können.

  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL



Zurück Weiter