Rainer's profileCyrons BlogPhotosBlogListsMore ![]() | Help |
|
|
March 29 Wikipedia bekommt 3 Mio $ Spende von der Alfred P. Sloan StiftungDiese Schlagzeile ist zur Zeit ziemlich allgegenwärtig im Internet. Alfred P. Sloan gründete diese Stiftung im Jahre 1934. Mehr dazu hier http://de.wikipedia.org/wiki/Alfred_P._Sloan besser noch ist dieser Link: http://en.wikipedia.org/wiki/Alfred_P._Sloan_Foundation Die Eckpunkte sind also: Alfred P. Sloan war der CEO von General Motors. Er schuf einige Innovationen auf dem unternehmerischen Sektor. Um es erst einmal ganz grob zu definieren, er war ein auf Profitmaximierung ausgerichteter Mensch. Nun zur Stiftung, da gibt der englische Artikel bessere Auskunft. Sie unterstützt Forschung, Entwicklung, Bildung und Karrieren in den Bereichen Wissenschaft, Technologie, Lebensstandards (?) und ökonomische Performance. Lebensstandards und ökonomische Performance? Klingt das nur für mich nach, "Lasst uns sehen, wie weit wir die Gesellschaft ausbeuten können, bevor sie kollabiert" ? Auf mich macht das jedenfalls keinen guten Eindruck. Was passiert jetzt, wo Wikipedia diese Spende bekommt? Ich fürchte, damit hat sich die größte Wissensbibliothek seit Alexandria in die Abhängigkeit manövriert. Wird Wikipedia, seiner Freiheit beraubt, noch genau so glaubwürdig sein? Wird es weiterhin ein objektiver Raum ohne Werbung sein? Kommentare sind erbeten. March 24 foreach, IEnumerable und IEnumeratorWas hat es mit der foreach-Schleife auf sich? Diese Frage möchte ich hier beantworten. Dazu erst ein Beispielcode von MSDN (Copyright by Microsoft). using System; using System.Collections; namespace IEnumeratorTest { class Book { internal Book(string name, decimal price) { Name = name; Price = price; } internal string Name { get; private set; } internal decimal Price { get; private set; } } class Library : IEnumerable { private Book[] books; #region ctors internal Library(Book[] bookArray) { /* So steht es zwar im MSDN-Sample, * aber das muß gar nicht so sein! */ //books = new Book[bookArray.Length]; //for(int i = 0; i < bookArray.Length; i++) //{ // books[i] = bookArray[i]; //} /* Es geht auch so: */ books = bookArray; } #endregion #region IEnumerable Members // Wird als erstes von der foreach-Schleife aufgerufen: public IEnumerator GetEnumerator() { return new BookEnumerator(books); } #endregion } class BookEnumerator : IEnumerator { private int counter = -1; internal Book[] books; internal BookEnumerator(Book[] list) { books = list; } #region IEnumerator Members // Wird als drittes von der foreach-Schleife aufgerufen: public object Current { get { try { return books[counter]; } catch(IndexOutOfRangeException) { throw new InvalidOperationException(); } } } // Wird als zweites von der foreach-Schleife aufgerufen: public bool MoveNext() { counter++; return (counter < books.Length); } // Wird von einer foreach-Schleife nicht benötigt: public void Reset() { counter = -1; } #endregion } class Program { static void Main() { Book[] bookList = new Book[2] { new Book("Erstes Buch", 1.00m), new Book("Zweites Buch", 2.00m) }; Library libraryList = new Library(bookList); foreach(Book item in libraryList) { Console.WriteLine(item.Name + " / " + item.Price.ToString()); } // Verhindert das selbsttätige Schliessen des Konsolenfensters. Console.WriteLine("\nBeenden mit Return"); Console.ReadLine(); } } } Codediskussion -> was im einzelnen passiertEs fängt mit der Klasse Book an, die ein passives Objekt mit mit zwei Eigenschaften (Name und Preis) verkörpert. class Book { internal Book(string name, decimal price) { Name = name; Price = price; } internal string Name { get; private set; } internal decimal Price { get; private set; } } Von diesem Objekt wird ein Array vom Typ Book und mit zwei Instanzen gebildet. Hier zu sehen ist die C#3-Variante dieser Arraybildung. Book[] bookList = new Book[2] { new Book("Erstes Buch", 1.00m), new Book("Zweites Buch", 2.00m) }; Als nächstes wird eine Klasse Library instanziiert, die das IEnumerable-Interface implementiert. Im Konstruktor wird das Buch-Array übergeben. Library libraryList = new Library(bookList); Die Instanziierung im Einzelnen: class Library : IEnumerable { private Book[] books; #region ctors internal Library(Book[] bookArray) { books = bookArray; } #endregion // Weiterer Code der Klasse Library, // der aber zu diesem Zeitpunkt noch keine Rolle spielt. //... Die Instanziierung ist damit abgeschlossen. Als nächstes folgt eine foreach-Schleife: foreach(Book item in libraryList) { Console.WriteLine(item.Name + " / " + item.Price.ToString()); } Diese macht nun Gebrauch von den Methoden, die durch die beiden Interfaces implementiert wurden. // Gehört zur Klasse "Library": #region IEnumerable Members // Wird am Anfang der foreach-Schleife aufgerufen: public IEnumerator GetEnumerator() { return new BookEnumerator(books); } #endregion Damit wird das Book-Array an den Konstruktor der Klasse BookEnumerator übergeben. class BookEnumerator : IEnumerator { private int counter = -1; internal Book[] books; internal BookEnumerator(Book[] list) { books = list; } Hier fällt auf, daß die Variable counter einen Wert von -1 erhält. Warum das so ist, sehen wir jetzt. // Wird als zweites von der foreach-Schleife aufgerufen: public bool MoveNext() { counter++; return (counter < books.Length); } Bevor irgend etwas aus dem Array ausgelesen wird, wird der Zähler um 1 inkrementiert. // Wird als drittes von der foreach-Schleife aufgerufen: public object Current { get { try { return books[counter]; } catch(IndexOutOfRangeException) { throw new InvalidOperationException(); } } } Wie man hier sieht, wird der Wert an der Pointerposition der books-Instanz zurückgegeben. Wir erinnern uns: Diese Instanz wurde durch den Aufruf von GetEnumerator() im Konstruktor der Klasse BookEnumerator gebildet und ist eine Kopie unseres Book-Arrays. Zum Schluß stehen noch zwei Fragen im Raum:
SchlußwortDieser Artikel spiegelt mein eigenes Verständnis wider. Es muß sich nicht zwingend mit dem offiziellen Verständnis decken. Ich kann vollkommen falsch liegen! Für konstruktive Kritik bin ich dankbar. March 05 Events in C#, ein einfaches BeispielDas Thema Events ist gerade für Beginner schwer verständlich. Ich spreche da aus eigener Erfahrung. Hier nun ein Beispiel das alles zeigt was für ein Event und Eventhandling nötig ist - ohne verwirrenden Schnickschnack. using System; namespace EventSimple { public class TestClass { // Der Delegat muß die gleiche Signatur aufweisen wie // die Eventhandler-Methode. public delegate void EventDelegate(); // Das Event-Objekt ist vom Typ dieses Delegaten public event EventDelegate MyEvent; public void OnEvent() { // Prüft ob das Event überhaupt einen Abonnenten hat. if(MyEvent != null) MyEvent(); } // Exemplarische Methode, // die unter einer bestimmten Bedingung ein Event auslöst. public void Observable() { Random rnd = new Random(); int result = rnd.Next(2); // Das Event wird gefeuert wenn result ungleich 0 ist. if(result != 0) OnEvent(); } } class Program { public static void Main() { TestClass tc = new TestClass(); // Hier wird das Event abonniert. // Das kann jede Klasse auf die gleiche Weise machen. tc.MyEvent += new TestClass.EventDelegate(EventHandler); tc.Observable(); } static void EventHandler() { Console.WriteLine("Event wurde ausgelöst."); } } } March 04 Lookup-Wert aus einer n:m Beziehung holenEine DataGridView soll befüllt werden. Zu Grunde liegen (unter anderen) die Tabellen
Ein Buch kann mehrere Themen behandeln, zu einem Thema gibt es aber auch viele Bücher - es handelt sich also um eine n:m Beziehung. In der Tabelle Book gibt es keine Referenz auf ein Thema. Der Zusammenhang zwischen beiden ist nur in der Crosstable sichtbar. Auch der O/R-Mapper (DBML-File) kann keine Wunder vollbringen. Eine LINQ2SQL-Expression muß hier also etwas komplexer ausfallen. Hier ist die Lösung (BookManagementDataContext ist die vom dbml-Designer erzeugte Mapper-Klasse): private void PopulateDataGridView() { Anmerkungen:
March 03 Erste Erfahrungen mit XAMLEinbindung eines Namespaces in ein XAML-FormFür eine Demo der ValueConversionAttribute-Klasse hatte ich eine eigene Klasse geschrieben und ihr den Namespace ValueConversionDemo gegeben.
Auf Deutsch, der Namespace konnte nicht gefunden werden. Die Lösung ist so einfach wie bescheuert: |
|
|