z.B. ist es nicht ohne weiteres möglich DLL-Funktionen von CSharp für mit VS 6.0 C++ erstellte Programme zu exportieren. (Stichwort vtable entry manuell ergänzen in IL-Code)
Es ist nicht ohne weiteres möglich bei (generischen) Listen für Add und Remove Events auszulösen.
Es ist nicht möglich Attribute ohne Reflection zur Ausführung zu bringen, in dem Sinne, wie es z.B. PostSharp ermöglicht.
Es kann kein Code zur Laufzeit/Compilezeit verändert werden und damit die Assembly zur Laufzeit verändert werden.
Keine Mehrfachvererbung im Sinne von C++
Nachgeladene Assemblies können nicht entladen werden (mal abgesehen über den Ausweg von AppDomain)
Welche Features fehlen euch?
Egal ob diese in Richtung der genannten Beispiele gehen oder nicht.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von dr4g0n76 am .
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
es ist aber nicht möglich, im Enhancer-Sinne (s. dazu [gelöst] Event auf Methoden-Aufruf über Attribute)
Code zur Laufzeit/Compilezeit mit Boardmitteln von C# zu verändern,
auch bezogen auf die eigene Assembly in der man sich gerade befindet.
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
Die meisten deiner genannten Merkmale sind aber nicht C# spezifisch sondern gründen in .Net.
Zum Beispiel das Entladen der Assemblies, die nichtvorhandene Mehrfachvererbung, die Änderung vorhandenen Codes zur Laufzeit usw.
Das wird nicht durch C# sondern durch die CLI und das CTS vorgeschrieben.
Genauso das Auslösen der Events bei den Collections, das liegt wiederum in der BCL und nicht in C#
Es ist wirklich schwer reine Merkmale von C# aufzulisten, aber es gab mal nen Thread hier dazu wo es vor allem um die fehlende Transparenz bei den Typen ging(bei Verwendung von Variablen nicht erkennbar ob es Werte oder Referenztypen sind, bei C++ z.b. leicht erkennbar anhand ob nun nen *, & bzw. . oder -> benutzt wird), und auch Properties die nicht als solche erkannt werden und Fehler provozieren können.
Praktisch alle Features von CΩ :) Okay, der Datenzugriff wurde in Form von Linq schon eingebaut, aber die asynchronen Methoden und Streams sind auch klasse.
Wenn Du dir die möglichkeiten von der 3.5 anschaust, und speziell etwas wie
Jasper siehst, dann wünsche ich mir das schon lange in VB.NET und IronPython
mögliche LateBinding.
Wenns geht mit einem Schlüsselwort, und ständigem nicht abschaltbaren
gemecker vom Compiler, damit es nicht zur gewohnheit wird ;-)
von dem, was du gesagt hast, stören mich eigentlich nur diese beiden Punkte:
Zitat
Es ist nicht ohne weiteres möglich bei (generischen) Listen für Add und Remove Events auszulösen.
Es ist nicht möglich Attribute ohne Reflection zur Ausführung zu bringen, in dem Sinne, wie es z.B. PostSharp ermöglicht.
Wobei mich eigentlich nicht stört, dass man Reflection benutzen muss. Mich stört eher, dass man in einer Methode/Propertie nicht einfach sagen kann: Gib mir alle "meine" Attribute.
Und der Punkt mit Add/Remove ist eher eine Folge einer allgemeineren Schwäche von C#:
- Methoden sind nicht per default virtual.
Ich weiß zwar auch, warum das so ist, aber ich denke, die Vorteile würden überwiegen, wenn alle Methoden virtual wären.
Dann gibt es noch eine Kleinigkeit, die mich aber nicht wirklich stört. Eher einer kleine Unebenheit der Sprache:
- Properties können nicht bei out oder ref verwendet werden.
Dass das nicht geht kann ich gut nachvollziehen! Es würde viel zu viele Probleme mit sich bringen, weil es gibt endlose Situationen, in denen nicht klar entschieden werden kann, welche "Überladung" genommen werden soll. Ein simples Beispiel:
Ich hoffe du kannst nachvollziehen, warum es dieses "Feature" nicht gibt.
Gruß,
Thomas
A wise man can learn more from a foolish question than a fool can learn from a wise answer! Bruce Lee
Populanten von Domizilen mit fragiler, transparenter Außenstruktur sollten sich von der Translation von gegen Deformierung resistenter Materie distanzieren! Wer im Glashaus sitzt, sollte nicht mit Steinen werfen.
naja, ich finde eher das Argument, dass man den Rückgabewert gar nicht übernehmen muss, bzw. dass durch das Überladen von Rückgabewerten das Übernehmen des Rückgabewerts erzwungen werden würde.
Denn das nicht Eindeutigkeitsproblem hat man ja auch beim Überladen von Parametern (ohne dass deshalb das Überladen von Parametern verboten wäre):
error CS0121: Der Aufruf unterscheidet nicht eindeutig zwischen folgenden Methoden und Eigenschaften: Bsp.Multiplizieren(decimal, decimal) und Bsp.Multiplizieren(double, double).
Ich hätte mir schon mal etwas ähnliches gewünscht: Das Überschreiben (nicht überladen) mit einem Rückgabe-Typ der vom vorherigen Rückgabe-Typ ableitet:
class A {}
class B : A {}
class X
{
public virtual A Foo()
{ ... }
}
class Y : X
{
public override B Foo()
{ ... }
}
Wobei B zwingend von A erben muss. Afaik gibt es OO Sprachen die das unterstützen.
Naja, ich will ja nix sagen, aber auch statische lokale Variablen gibts bei VB.NET, die sind im IL-Code auch als Klassenvariablen implementiert. Wenn ich eine statische Integer-Variable mit dem Namen i in einer Methode Test anlege, dann erzeugt VB automatisch die Klassenvariable $STATIC$2001$Test$i, die im IL-Code mit dem Modifikator specialname ausgestattet ist.
da der Thread aber "Limits von C# / CSharp" und nicht "Features von VB / VisualBasic" heißt, ändert es nichts an dem Limit von C#, wenn es das Feature in VB gibt. :-)
Die Aussage sollte sein, dass das vermeintliche Feature von anderen Sprachen, statische lokale Variablen anlegen zu können (z.B. eben VB.NET), nur eine reine Compilezeitgeschichte ist, und damit in meinen Augen nicht wirklich ein Limit...
ja, aber VB sorgt dann dafür, dass obwohl es intern eine Klassenvariable benutzt, auf diese nur aus der jeweiligen Methode zugegriffen werden kann. Wenn man in C# "von Hand" eine Klassenvariable benutzt, muss man darauf selber aufpassen. Insofern ist es schon ein kleines Limit (im Sinne von Schwäche) von C#, wenn der Compiler keine lokalen statischen Variablen unterstützt.
Ich persönlich finde die Generics nicht ganz überzeugend. Diese komische Zwitterverhalten (Compile- vs. Laufzeit) ist manchmal sehr lästig - auch wenn mir klar ist, dass es da nix zu verbessern gibt, ohne .NET komplett umzukrempeln.
{ und } können das Ende eines beliebigen Codeabschnitts sein, also von
- einer Klassendefinition
- einer Methodendeklaration
- einer Struktur
- einer Enumeration
- einer Eigenschaft
- einer Get-Deklaration
- einer Set-Deklaration
...
u.v.m.
Ich hab vor einiger Zeit ja mal ein Progrämmchen programmiert um bestehenden Quellcode zu sortieren, da ging's dann im Parser drum zu erkennen, was der gerade eingelesene Code nun darstellt, um z.B. die Eigenschaften zu sortieren und auszulagern. Eine nicht funktionierende Vorversion davon für VB.NET (das sagt einem ja, welcher Codeabschnitt gerade beendet wird) steht auch irgendwo unter Projekte. Bei C# ist sowas aber viel aufwändiger, weil man die ganze Zeit die { und } mitzählen muss (außerdem ist eine Felddefinition nicht wirklich erkennbar)
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von onlinegurke am .
bis auf die größere Sichtbarkeit entsprechen Klassenvariablen dem, was du willst.
herbivore
Und genau auf die Sichtbarkeitsunterschiede kommt es mir auch an :D. Ich dachte mit meinem Beispiel kann ich das etwas verdeutlichen. Öfters brauche ich eine Variable nur in einer Funktion, dafür aber "statisch". Diese Variable als Membervariable zu deklarieren ist unübersichtlicher.
{ und } können das Ende eines beliebigen Codeabschnitts sein, also von
- einer Klassendefinition
- einer Methodendeklaration
- einer Struktur
- einer Enumeration
- einer Eigenschaft
- einer Get-Deklaration
- einer Set-Deklaration
...
u.v.m.
Ich hab vor einiger Zeit ja mal ein Progrämmchen programmiert um bestehenden Quellcode zu sortieren, da ging's dann im Parser drum zu erkennen, was der gerade eingelesene Code nun darstellt, um z.B. die Eigenschaften zu sortieren und auszulagern. Eine nicht funktionierende Vorversion davon für VB.NET (das sagt einem ja, welcher Codeabschnitt gerade beendet wird) steht auch irgendwo unter Projekte. Bei C# ist sowas aber viel aufwändiger, weil man die ganze Zeit die { und } mitzählen muss (außerdem ist eine Felddefinition nicht wirklich erkennbar)
Mit Xml kannst du auch viele geschachtelte Sachen auslesen. Ich finde das ist nicht so das große Problem.
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...
Generics haben tatsächlich noch einige Schwächen, vor allem in den Constraints. Was zum Beispiel fehlt:
- Parameter für den Konstruktor (z.B. where Foo : new(int, double))
- Operatoren (z.B. where Foo : operator+(Foo, Foo)), das würde endlich generische mathematische Algorithmen ermöglichen
Was mir sonst noch einfällt:
Indizierte Properties (außer this), VB und C++/CLI können es nämlich:
Also etwa:
public class Foo {
List<string> wörter;
List<int> zahlen;
public string Wörter[int index] {
get { return wörter[index]; }
}
public int Zahlen[int index] {
get { return zahlen[index]; }
}
}
Eine der größten Schwächen in der BCL ist meiner Meinung nach die sehr schwache Collections-Bibliothek. Zum einen unvollständig, zum anderen würde ich mir eine stärkere Aufspaltung zwischen lesenden und schreiben Funktionen wünschen. ICollection hat z.B. immer eine Add/Remove/Clear-Methode, auch wenn die Collection Schreibgeschützt ist. Ich fände es besser, wenn alle lesenden Eigenschaften und Methoden in ein eigenes Interface ICollectionView oder so fließen würden und ICollection dann von ICollectionView erbt und Add/Remove/Clear zufügt. Dadurch könnte man schon zur Compilezeit die Nur-Lesbarkeit einer Collection ausdrücken, indem man dem client nur ein ICollectionView-Objekt zur Verfügung stellt. Entsprechendes müsste dann auch mit IList und IDictionary gemacht werden. Ich sehe allerdings ein, dass das die Anzahl der Interfaces und Klassen drastisch erhöhen würde. Ist halt ein Trade-Off zwischen Funktionalität und Übersicht.