myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
   » Plugin für Firefox
   » Plugin für IE
   » Gadget für Windows
» Regeln
» Wie poste ich richtig?
» Datenschutzerklärung
» wbb-FAQ

Mitglieder
» Liste / Suche
» Stadt / Anleitung dazu
» Wer ist wo online?

Angebote
» ASP.NET Webspace
» Bücher
» Zeitschriften
   » dot.net magazin
» Accessoires

Ressourcen
» .NET-Glossar
» guide to C#
» openbook: Visual C#
» openbook: OO
» .NET BlogBook
» MSDN Webcasts
» Search.Net

Team
» Kontakt
» Übersicht
» Wir über uns
» Bankverbindung
» Impressum

» Unsere MiniCity
MiniCity
» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Knowledge Base » Artikel » [Artikel] C# 3.0: Spracherweiterungen
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

[Artikel] C# 3.0: Spracherweiterungen

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Noodles
myCSharp.de-Poweruser/ Experte

Dabei seit: 08.02.2004
Beiträge: 4.646
Herkunft: Leipzig


Noodles ist offline

[Artikel] C# 3.0: Spracherweiterungen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Automatische Eigenschaften
Bei automatischen Eigenschaften handelt es sich um ein Feature, bei dem der Compiler automatisch die privaten Felder einer Eigenschaft setzt. Der ein oder andere hat sich vielleicht schon über das "seltsame" Verhalten des Codesnippets in Visual Studio 2008 gewundert,

C#-Code:
// bisher
private string firstName;
public string FirstName
{
    get { return firstName; }
    set { firstName = value; }
}

// ab Visual Studio 2008
public string FirstName { get; set; }

Erweiterungsmethoden
Durch Erweiterungsmethoden können zum Beispiel zu versiegelten Typen Methoden hinzugefügt werden. Es bestand das Problem auf IEnumerable<T> Methoden aufzurufen. Allerdings kann man ja dem Interface keine Methoden nachträglich hinzufügen. Es sei denn, man nimmt in Kauf das ein gewisse Anzahl von Anwendungen mit diesem Framework nicht mehr funktionieren würden. Erweiterungsmethoden müssen in einer statischen Klasse, als public und statisch definiert sein. Der erste Parameter wird mit einem this vor dem Datentyp gekennzeichnet. Daran und an dem Schlüsselwort static erkennt der Compiler die Erweiterungsmethode.

Beispiel für eine Erweiterungsmethoden

C#-Code:
public static bool IsInRange( this int source, int min, int max )
{
    return ( source > min && source < max );
}

// auf jedes IEnumerable<T> anwendbar.
public static T Where<T>( this IEnumerable<T> source, Func<T, bool> func )
{
    // ...
}

Objektinitialisierer
Objekte werden ja normalerweise Konstruktoren oder Properties initialisiert. Das funktioniert in C# 3.0 etwas einfacher. Das ist aber keine Magie, auch keine neuen MSIL Anweisungen. Der Compiler wandelt es um und ruft einfach nur die Setter auf.

C#-Code:
Person person = new Person { FirstName = "Max", LastName = "Mustermann" };

Die Konstruktorklammern müssen nicht, können aber mitgeschrieben werden. Es kann auch ein benutzerdefinierter Konstruktor erstellt werden, um die Initialisierung eines Members zu erzwingen.

Collectioninitialisierer
Wie es Objektinitialisierer gibt, gibt es auch Collectioninitialisierer. Was nun selbsterklärend sein sollte.

C#-Code:
List<Person> persons = new List<Person>
{
    new Person { FirstName = "Max", LastName = "Mustermann" },
    new Person { FirstName = "Tina", LastName = "Tester" }
};

Implizit typisierte lokale Variablen
In C# 3.0 wird bzw. kann der Datentyp einer Variablen automatisch vom Compiler bestimmt werden. Dies geschieht über das Schlüsselwort var. Vorweg, diese Art der Zuweisung ist typsicher. Ist einer Variable einmal ein Typ vom Compiler zugewiesen worden, kann man dieser keinen anderen Datentyp mehr zuweisen.

C#-Code:
var intValue = 1;
Console.WriteLine( intValue.GetType() ); // System.Int32
//intValue = 1.2; // Fehler

Es sind aber ein paar Dinge zu beachten.
- var darf nicht verwendet werden:
  • als Member in Klassen und Strukturen
  • als Funktionsparameter
  • als Rückgabewert einer Funktion
- var muss bei der Deklaration sofort initialisiert werden
- var darf nicht mit null initialisiert werden

Anonyme Typen
Aus LINQ Abfragen können von Objekten einige, alle oder mehr Eigenschaften in einem neuen Objekt zurückgegeben werden.

Beispiel:

C#-Code:
IEnumerable<PersonWithFullName> query = from c in customers
                                        select new PersonWithFullName
                                        {
                                            FirstName = c.FirstName,
                                            LastName = c.LastName,
                                            FullName = c.FirstName + " " + c.LastName
                                        };

Dafür habe ich eine Klasse PersonWithFullName geschrieben. Wie man sich schnell vorstellen kann, kann das sehr ausufernd werden und zu einer "Klassenexplosion" führen. Dafür wurden anonyme Typen eingeführt. Bei anonymen Typen legt der Compiler den Typ an.

C#-Code:
var query = from c in customers
            select new { c.FirstName, c.LastName, FullName = c.FirstName + " " + c.LastName };

Es wird nach dem new einfach ein Objekt initilisiert und einer Variable mit dem Typ var zugewiesen. Daraus entsteht in diesem Fall ein IEnumerable<%TypDesAnonymenTypen%>.

Lambda Expressions
Der Nachfolger von anonymen Methoden. Eine Art Funktionszeiger. Das im ersten Moment auffälligste an einer Lambda Expression ist der Doppelpfeil ( => ). Links von dem Doppelpfeil steht die Parameterliste und rechts der Ausdruck. Der Rückgabetyp wird aus dem Typ des Ausdrucks bestimmt.

C#-Code:
int[] values = { 1, 3, 4, 6, 88, 66, 453 };
Array.ForEach( values, i => Console.WriteLine( i ) );

Das i vom Typ int sein muss, kann der Compiler aus values ableiten. Diese Lambda Expression entspricht folgender anonymen Methode:

C#-Code:
Array.ForEach<int>( values, delegate (int i) { Console.WriteLine(i); } );

Diese anonyme Methode kann man auch folgendermaßen ausdrücken.

C#-Code:
Array.ForEach<int>( values, ShowNumbers );

private void ShowNumbers( int i )
{
    Console.WriteLine( i );
}

Weiteres Beispiel für Lambda Expressions:

C#-Code:
( a, b ) => a + b
// Zwischenspeichern
Func<int, int, int> myFunc = ( a, b ) => a + b;

Func ist ein delegate der mit dem .NET Framework 3.5 eingeführt wird und in vielen Erweiterungsmethoden zum Einsatz kommt.

Bei den meisten Spracherweiterungen sieht man die Nützlichkeit und den Sinn wohl erst im Einsatz mit LINQ.

Suchhilfe: Spracherweiterung
18.11.2007 20:37 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
norman_timo norman_timo ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-1775.jpeg


Dabei seit: 13.07.2004
Beiträge: 4.506
Entwicklungsumgebung: .NET 2.0/3.5 und VS2005/VS2008
Herkunft: Wald-Michelbach (Odw)


norman_timo ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Noodles,

vielen Dank für Deine Beispiele, so kann man sich neue Sprachfeatures auch mal ohne gleich ein Buch kaufen zu müssen ausprobieren.

Eine kleine Frage hätte ich doch zu automatischen Eigenschaften:

Woher weiß der Compiler welches private Feld er denn hernehmen muss. Gibt es da irgendwelche Namenskonventionen, die man einhalten muss (entsprechend, weil bei mir z.B. alle privaten Felder mit "m_" beginnen, die Eigenschaften entsprechend natürlich nicht?

Grüße
Norman-Timo
18.11.2007 21:15 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
talla talla ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-3214.jpg


Dabei seit: 20.07.2003
Beiträge: 6.863
Entwicklungsumgebung: VS 2010
Herkunft: Esslingen


talla ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Bei welchem Feature meinst du norman_timo?

Den automatischen Properties? Falls ja, da legt man gar keine privaten Felder mehr an, das macht der Compiler automatisch. Sprich das Feature nutzt nur was wenn man wirklich nur stur Variablen durch Properties veröffentlichen will, sobald eigene Logik in die Properties rein soll, schreibt man sie ganz normal wie gehabt.
18.11.2007 21:28 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
feadur feadur ist männlich
myCSharp.de-Mitglied

Dabei seit: 11.03.2005
Beiträge: 722
Herkunft: Bonn


feadur ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

hallo zusammen,

wie kann ich dem property denn dann in der klasse die es definiert, einen wert zuweisen, wenn ich den setter entferne?

also sowas wie

C#-Code:
class MyClass
{
public int Zahl { get; }

public MyClass()
{
    Zahl = 2; // Das geht nicht...
}
}

falls es keinen zugriff auf das private feld gibt, dürfte das ja gar nicht funktionieren, oder? Ich nehme also mal an, dass man bei automatischen Properties den setter nicht entfernen darf?

gruß

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von feadur am 18.11.2007 22:14.

18.11.2007 22:13 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
talla talla ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-3214.jpg


Dabei seit: 20.07.2003
Beiträge: 6.863
Entwicklungsumgebung: VS 2010
Herkunft: Esslingen


talla ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
Original von feadur
Ich nehme also mal an, dass man bei automatischen Properties den setter nicht entfernen darf?

So ist es, bei automatisch implementierten Properties muss immer beides vorhanden sein.
18.11.2007 22:20 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
norman_timo norman_timo ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-1775.jpeg


Dabei seit: 13.07.2004
Beiträge: 4.506
Entwicklungsumgebung: .NET 2.0/3.5 und VS2005/VS2008
Herkunft: Wald-Michelbach (Odw)


norman_timo ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo talla,

danke für Deine Antwort. Ja ich habe geschrieben, dass ich das im Bezug zu automatischen Eigenschaften meinte.

Zitat:
Sprich das Feature nutzt nur was wenn man wirklich nur stur Variablen durch Properties veröffentlichen will

Das würde für mich nun konkret bedeuten, dass das A) anders herum funktioniert wie ich es implementieren würde, und B) dass es für mich nicht anwendbar ist, weil ich eben die privaten Felder besonders markieren möchte, was die Automatik ja nicht macht.

Zu A) -> Ich entwickle normalerweise Klassen so, dass ich zunächst alles definiere was ich für die Klasse benötige. Erst danach überlege ich mir, was ich öffentlich machen möchte...

Aber für andere mag das ja dann Sinn machen.

Vielen Dank,
Norman-Timo
19.11.2007 07:21 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
talla talla ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-3214.jpg


Dabei seit: 20.07.2003
Beiträge: 6.863
Entwicklungsumgebung: VS 2010
Herkunft: Esslingen


talla ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

oh ja, mein Fehler :/ Hatte wohl mal wieder meine 5 blinden Minuen *gg*

Erstmal zu B): Du hast ja dann gar keine expliziten privaten Felder mehr. Wenn man aber dann halt private Felder mit diesen automatischen Properties mischt, sprich man muss einige Properties selber in der Klasse setzen, andere Werte setzt man in privaten Feldern, dann wirkt das schon ein wenig inkosistent.

Wo ich mir die aber gut vorstellen kann sind Code Generatoren, wenn z.B. irgendwelche komplexen Datenklassen erstellt werden, da verkürzt sich der Code erheblich wenn nicht immer explizit nen privates Feld angelegt werden muss.

Zu A): Da kommt ja der Gedanke heraus - ich muss ja eh ein privates Feld für nen Property erstellen - also erstmal alles privat erstellen smile Weiß nicht, vielleicht ist das Gewöhnungssache ob man nicht doch gleich Properties schreibt. Wenn ich weiß das meine Klasse bestimmte Properties zur Verfügung stellen soll, dann mach ich die meistens gleich als Properties - von daher kommen die automatischen Properties mit ein wenig entgegen, was aber auch nicht heißt das ich sie laufend verwenden werde, halt mal sehen was sich so anbietet.
19.11.2007 07:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Team (Admin)

images/avatars/avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.001
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo zusammen,

was wohl ein guter Abschluss der Diskussion an dieser Stelle ist. Wenn einzelne Sprachfeaures ausführlicher besprochen werden sollen, als man das in 4-5 Beiträgen machen kann, öffnet bitte einen neuen Thread. Vielen Dank!

herbivore
19.11.2007 08:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegen mehr als 2 Monate.
eclere eclere ist männlich
myCSharp.de-Mitglied

Dabei seit: 27.01.2006
Beiträge: 90
Entwicklungsumgebung: Visual Studio 2008 Standard


eclere ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

ohne die Diskussion neu anheizen zu wollen würde ich dennoch die Frage von feadur gerne beantworten.

Man kann auch schreiben:

C#-Code:
public string FirstName { get; internal set; }

Gruß Thorsten
04.02.2008 14:44 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
userid4382
myCSharp.de-Mitglied

Dabei seit: 14.04.2006
Beiträge: 239


userid4382 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Automatische Readonly-Properties kann man so schreiben (hab ich gerade in der MSDN-Hilfe gefunden):

C#-Code:
public IQueryProvider Provider { get; private set; }
13.02.2008 13:25 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 6 Jahre.
Der letzte Beitrag ist älter als 6 Jahre.
Antwort erstellen


© Copyright 2003-2014 myCSharp.de-Team. Alle Rechte vorbehalten. 23.10.2014 04:15