Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Portal
  • |
  • Mitglieder
Beiträge von DerKleineTomy
Thema: Mit foreach- und for-Schleifen über ein Array iterieren
Am im Forum: Grundlagen von C#

2. Um Leerzeichen mitten aus einem String zu entfernen, bietet sich z.B. String.Replace an.


string textWithWhitespace = "This text has whitespaces"
string textWithoutWhitespace = textWithWhitespace.Replace(" ", ""); // Leerzeichen " " durch nichts ersetzen ""

3. Die Antwort gehört auch teilweise zu 6.: Du solltest nicht immer nur auf die Ausgabe mit Console.WriteLine() achten. Willst du z.B. den string NICHT ausgeben und nur in einer Variablen speichern, oder willst du ihn für die SPÄTERE Ausgabe zwischenspeichern, dann kommst du um String.Format() nicht drumherum. Console.WriteLine() benutzt im Hintergrund nichts anderes als String.Format.

4. text.Length ist die Anzahl der einzelnen Chars im String. Da aber ein Array generell mit Index 0 und nicht 1 anfängt, musst du bei der For-Schleife von 0 bis text.length - 1 zählen. Hat dein String z.B. Length 10, dann ist der höchste Index 9 und nicht 10.

for (int i = 0; i < inverted.Length; i++)
{ inverted [i] = text [inverted.Length - 1 - i]; }
Es geht ja darum, dass der Text invertiert, also von hinten nach vorne, gespeichert wird. Du willst also deinen Text von hinten nach vorne durchlaufen, also fängst du mit dem höchsten Index an (inverted.Length - 1) und ziehst dann i ab. In anderen Worten, du zählst runter und nicht rauf. Übrigens finde ich an dieser Stelle [text.Length - 1 - i] etwas schöner, aber macht keinen Unterschied, da text.Length == inverted.Length ist.

5. Nullable ist nur für Wertetypen gedacht. Alle Referenztypen (darunter auch String) können bereits den Wert null annehmen. Was der Unterschied von Referenz- und Wertetypen ist, wird vermutlich noch später in dem Buch behandelt (wenn noch nicht geschehen).
Dementsprechend ist ein nicht zugewiesener String tatsächlich einfach:

string nullString = null;
string emptyString = String.Empty; // oder ""
Beachte, dass ein leerer String anders ist, als ein null-String.

6. Wie in 3. bereits angesprochen: Wenn du die Zahl nur ausgeben willst, dann macht es keinen Unterschied, aber wenn du den tatsächlichen Wert zwischenspeichern willst, dann schon. Z.B. macht auch folgendes keinen Unterschied bezüglich der Ausgabe, ist aber inhaltlich schon etwas anders:

string myNumber = "5";
int myNumber2 = 5;
long myNumber3 = 5;
Console.WriteLine(myNumber);
Console.WriteLine(myNumber2);
Console.WriteLine(myNumber3);

Thema: Codegeneriung: protected internal Methode überschreiben
Am im Forum: Rund um die Programmierung

Es ist ganz einfach so, dass du eine protected internal Methode nur mit dem Keyword protected überschreiben kannst.


public class A
{
       protected internal void MyMethod() {}
}


// Andere Assembly

public class B : A
{
     protected internal override MyMethod() {} // Error
     protected override MyMethod() {} // Korrekt
}


Das hat den einfachen Grund, dass "protected internal" die Bedeutung "protected" ODER "internal" hat. Könntest du mit "protected internal" aus einer Assembly B überschreiben, dann wäre die Methode in Assembly B global sichtbar (da Internal), was aber der original deklarierten Methode aus Assembly A widerspricht (nur in Assembly A oder in abgeleiteten Klassen sichtbar).

Thema: Funktionsweise von Methoden als Parameter in Methodenaufrufen [==> Delegaten]
Am im Forum: Grundlagen von C#

Ich glaube du verwechselst Events und Delegates. Delegates sind einfach gesagt nur Referenzen auf Methoden. Du kannst diese dann einfach wie jede andere Methode auch aufrufen. Dabei muss antürlich die Signatur der aufzurufenden Methode bekannt sein. In deinem Fall sagt

Func<T, int, string>
dass es sich um eine Methode handelt, die ein Objekt von Typ T und einen Int als Argument bekommt und einen String zurückliefert.

Events hingegen benutzen zwar im Hintergrund nichts anderes als Delegates, aber sie bieten noch einen Zugriffsschutz von außen. Außenstehende Klassen z.B. können sich nur am Event registrieren (es abonieren), aber nicht selber auslösen (das Delegate dahinter ausführen).

public class MyClass
{
    public event Action<String> MyEvent;
    public Action<String> MyAction;
}

public class MyOtherClass
{

     public static void Main()
     {
         Action<String> action = (x) => System.Console.PrintLine(x);
         MyClass c = new MyClass();
         c.MyEvent += action; // Event abonieren
         c.MyAction = action; // Delegate setzen
         c.MyEvent("Some String"); // Error, da du das Event nicht von außen aufrufen kannst
         c.MyAction("Some String"); // Funktioniert, da das Feld MyAction auf eine Methode zeigt und diese somit aufgerufen wird
     }
}


Prinzipiell passiert bei dem Event und bei dem Delegate dasselbe, aber u.A. können Events nur von der implementierenden Klasse ausgelöst werden.

Thema: Variabel Generator Visual Studio 2013
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Was soll das ganze bringen? Wenn du letztendlich doch wieder für jede Variable den Typ, den Namen und sonstiges angibst, hast du doch absolut nichts gespart.
Außerdem schreit 700 Variablen nach einem Designfehler (vielleicht solltest du eher ein Array bzw. eine List verwenden?). Bei Controls, die du auf die Form ziehst (z.B. Textbox) kannst du im Designer einen Variablennamen und die Sichtbarkarkeit übrigens angeben, falls sich die Frage auf Controls bezieht.

Thema: Polnische Notation / Array-Elemente vergleichen
Am im Forum: Grundlagen von C#

Auch wenn die der Anfangspost etwas ungünstig formuliert war, hab ich mir schon fast gedacht, dass es sich um eine Konvertierung von Infix in UPN handelt.

Was du wahrscheinlich versuchst zu programmieren ist der Shunting-Yard Algorithmus.

Um herauszufinden, ob das momentane Element eine Klammer, ein Operator oder eine Zahl ist, kannst du doch simple Vergleiche benutzen.

1) Klammer: Element ist "(" oder ")"
2) Operator: Element ist "+", "*", "-", .... (sonstiges). Hier bietet es sich an ein Array mit allen gültigen Operatoren anzulegen (oder sogar ein HashSet) und einfach ein Lookup darin zu machen.
3) Zahl: int.TryParse oder float.TryParse (falls Kommazahlen auch erlaubt sind) sind vermutlich die einfachsten Methoden dafür.

Thema: ObservableCollection protected PropertyChanged
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Es ist nunmal (design-technisch) gewollt, dass die Interfaceimplementierung explizit ist und explizite Implementierungen können nicht als virtual deklariert werden. Es ist somit der einzige Weg eine Methode sowohl explizit als auch virtual zu implementieren.

Thema: Mehrere Event Methoden bei gleichen Event
Am im Forum: Rund um die Programmierung

Zitat von h4x0r_
'Fügt hinzu' und 'nimmt den Wert an'

Eben, und deswegen funktioniert += auch. Du nimmst den momentanen Wert, fügst die neue Methode hinzu und schreibst das Gesamte wieder in das Event.

Die Reihenfolge, in der die Eventhandler ausgeführt werden, ist in der Regel identisch zu der Reihenfolge in der die Handler hinzugefügt wurden. Zudem lässt sich da an der Reihenfolge nichts mit ein "paar" Verzweigungen lösen. Dein Vorhaben lässt sich definitiv auch mit nur einer einzigen Methode lösen, die alle anderen Methoden in einer bestimmten Reihenfolge aufruft (eben genau das macht ja ein Event).

Thema: ListBox Items aktualisieren
Am im Forum: GUI: WPF und XAML

Es hört sich so an, als ob du immernoch Probleme hättest. Wenn dem so ist, dann beschreib dein Problem genauer, damit wir dir helfen können.
Zu deinem Problem aus dem ersten Post habe ich dir bereits gesagt wieso das auftritt und wie du es lösen kannst.

Thema: ListBox Items aktualisieren
Am im Forum: GUI: WPF und XAML

Wenn du die ListBox mit listBox.Items.Clear() leerst, wird vermutlich das SelectionChanged Event ausgelöst, da nun kein Item mehr selektiert ist (sind ja alle weg). In deinem Event Handler liest du den neuen SelectedIndex aus, der aber -1 ist, da kein Item selektiert ist. In der Zeile:

txtbAusgabe.Text = textblock[index];
kommt es dann zu ArgumentOutOfRangeException, da -1 kein gültiger Arrayindex ist.

=> Prüfe einfach, ob der Index != -1 ist, bevor du auf das Array zugreifst.

Und übrigens:

     //Ermittle den gewählten Item von ListBox und ordne es den Vaibalen index zu
     int index = lstbWahl.SelectedIndex;

     //überprüfen welche der Items gewählt wurde
     if (lstbWahl.SelectedIndex == index)
          txtbAusgabe.Text = textblock[index]; //den entsprechen Text in TextBox ausgeben

Der Code macht so keinen Sinn. Der Ausdruck lstbWahl.SelectedIndex == index wird immer true liefern, da du index gerade erst mit lstbWahl.SelectedIndex initialisiert hast.

Thema: [erledigt] Per Reflection.Emit einen Event mit explizitem add und remove generieren
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

In deinem Code fügst du auch keine Add oder Remove Methode zu dem Event hinzu.

EventBuilder ev = _tb.DefineEvent("PropertyChanged", EventAttributes.None, typeof(PropertyChangedEventHandler)); 

MethodBuilder addMethod = ...;
// Define Method ...
//...
ev.SetAddOnMethod(addMethod);

Daher ist auch keine Implementierung vorhanden.

Thema: Array Index - falscher Wert wird ermittelt
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Array.BinarySearch geht davon aus, dass das zu durchsuchende Array sortiert ist. Es kann also sein, dass du einen falschen Index erhälst, weil das Array nicht sortiert ist. Verwende also lieber

theArguments.IndexOf(...);

Ich finde es auch verwunderlich, dass du bei dem Zugriff auf theArguments den Index immer um einen erhöhst. BinarySearch bzw. IndexOf geben dir den korrekten Index.

Und was ist der Grund dafür, dass du zweimal hintereinander die selbe Methode aufrufst?

theArguments = theArguments.Where(...);
theArguments = theArguments.Where(...);

Thema: (Generische) Methode für Unterelemente erneut aufrufen (und nach dem Typ der Objekte unterscheiden)
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Gibt es überhaupt einen Grund die Methode generisch zu machen? In dem von dir gezeigten Code wird an keiner Stelle Gebrauch von Generika gemacht. Wenn möglich, solltest du die Methode mit object arbeiten lassen, dann hast du auch keine Probleme mit dem Casten, um den rekursiven Aufruf durchzuführen.
Falls es generisch sein muss, musst du Reflection verwenden um die passende Methode mit dem passenden generischen Argument aufzurufen:


MethodInfo convertClassToXmlDataMethod = ...;

// ... später
object aObj = ...;
MethodInfo m = convertClassToXmlDataMethod.MakeGeneric(aObj.GetType());
m.Invoke(this, aObj);

Der Code ist aus dem Gedächtnis geschrieben, also kann es sein, dass er so nicht korrekt ist. Vor allem bei m.Invoke() bin ich mir wegen der Parameterreihenfolge nicht sicher.

Thema: Member einer Klasse werden nicht gesetzt
Am im Forum: GUI: Windows-Forms

Kann es sein, dass deine beiden Formen Statistiken und Einwohner einfach nicht das selbe Spieler-Objekt referenzieren? Es sieht so aus als ob du zwar die Holzfälleranzahl in der Einwohnerform ändern kannst, aber die Statistikform mit ihrer eigenen Spielerinstanz rechnet und deswegen einfach keine Änderungen mitbekommen kann (da es nunmal keine gibt).

=> Erstell das Spielerobjekt nur einmalig und übergib die Referenz auf irgendeine Art und Weise an die verschiedenen Formen (z.B. über den Konstruktor).

Thema: Big-O-Notation: Wie groß ist der Aufwand für eine verschachtelte Schleife?
Am im Forum: Rund um die Programmierung

Sowohl deine äußere als auch deine innere Schleife haben exakt n Durchläufe, also sind es insgesamt n^2 Durchläufe (für jeden der n möglichen Werte von i, werden alle n Werte von j durchlaufen).
Wenn der Code innerhalb der zweiten Schleife nur konstante Laufzeit hat, also in O(1) liegt, ist somit deine gesamte Funktion in O(n^2).

@chilic: Es gibt keine Abhängigkeit zwischen den beiden Schleifen, also sind es exakt n^2 Schleifendurchläufe.

Thema: Nutzen eines abstrakten Konstruktor zum Erstellen abgeleiteter Klassen.
Am im Forum: Rund um die Programmierung

Du kannst auch einfach eine abstrakte Methode (z.B. Create) erstellen, die ein neues Objekt der Klasse liefert (also genau wie ein Konstruktor). In den Unterklassen überschreibst du diese in etwa so:


public abstract class Component
{
    protected abstract Component Create(...);

    public List<Component> AsItemList()
    {
        List<Component> result = new List<Component>();
        result.Add(Create("null", "", "First item"));
        result.AddRange(Descendants);

        return result;
    }
}

public class Segment : Component
{
    public Segment(...)
    {
        // Initialisieren
    }

    protected override Component Create(...)
    {
         return new Segment(...);
    }
}

Diese Methode ist zumindest besser als jedes mal die ganze AsItemList-Methode neu zu implementieren.

Thema: Überladener Konstruktoraufruf bei generische Klasse
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

1) Ohne Type-Constraints kann obj nicht null sein, da T auch ein Wertetyp sein kann.
2) Ohne ein Feld oder eine lokale Variable kannst du keine ref-Übergabe machen.
3) Ohne ref könntest du default(T) nutzen oder, falls du ein class-Constraint einbaust, auch direkt null.

Thema: Das Programmier-Spiel: nette Übungsaufgaben für zwischendurch
Am im Forum: Smalltalk

Super Aufgabe. Ohne in eine bestimmte Definition in der C# Spezifikation zu gucken, hätte ich wohl etwas länger daran geknabbert :). Die Lösung poste ich allerdings nicht, da ich zu einem keine Aufgabe habe und zum anderen den Spaß an der Aufgabe nicht vermasseln möchte :)

Edit: Da war jemand mit der Lösung etwas schneller.

Thema: Ermitteln, ob Punkt auf Linie liegt
Am im Forum: Rund um die Programmierung

Die Geradengleichung lautet y = mx + t

Nachdem du m = (y2 - y1)/(x2 - x1) ausgerechnet hast (Klammern nicht vergessen!) kannst du einfach deine Ausgangsgleichung y =mx + t nach t umformen => t = y - mx.
Dann setzt du für y und x einen der beiden Punkte ein (ist egal welchen).

private bool PunktAufLinie(PointF p1, PointF p2, PointF kP)
{
      double m = (p2.Y - p1.Y) / (p2.X - p1.X); // Steigung
      double t = p1.Y - m * p1.X; // Die Verschiebung entlang der y-Achse
      // double t = p2.Y - m * p2.X; ist auch möglich!

      double ykP = m * kP.X + t; // Berechne den Sollwert von kP.Y

      const double toleranz = 0.5; // Die erlaubte Abweichung vom Sollwert

      return Math.Abs(ykP - kP.Y) ≤ toleranz; // Ist der Abstand zwischen dem y-Wert des Kontrollpunktes und dem Sollwert des Kontrollpunktes innerhalb der Toleranzgrenze?
      
}

Noch als Zusatz: Die Funktion betrachtet nur die Differenz in den y-Werten und nicht den tatsächlichen Abstand zwischen dem Kontrollpunkt und der Geraden!

Thema: Typparameter erfüllt nicht die Anforderungen für weiteren Methodenaufruf
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Der Typparameter T in der Load<T>-Methode muss auch das new()-Constraint haben, da ansonsten T ein Typ sein kein, der eben keinen parameterlosen Konstruktor hat und somit nicht gültig für den Aufruf von GetAsync<T> ist.

Thema: Das Programmier-Spiel: nette Übungsaufgaben für zwischendurch
Am im Forum: Smalltalk

Auch hier meine Lösung:


a = (b - a) + (b = a);

Thema: Implementation eines Interfaces in Generischer Klasse
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Der Rückgabetyp der Property muss exakt mit der im Interface deklarierten Property übereinstimmen. Implementier einfach das Interface explizit wie folgt:


public interface IControlRenderer
{
     LabelControl Control { get; }
}

public abstract class ControlRenderBase<TLabelControl> :DrawingVisual,IControlRenderer where TLabelControl : LabelControl
{
     public TLabelControl Control { get; set; }

     LabelControl IControlRenderer.Control 
     {
         get { return this.Control; } // this.Control gibt den Wert der oben definierten Property zurück
     }
}

Auf diese Weise hast du die generische Property, wenn du über die Klasse selbst zugreifst und die nicht-generische Property, wenn du über das Interface zugreifst.

Thema: Per CodeDom zwei Int Werte vergleichen
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Der Ausdruck

a > b
lässt sich mit folgenden CodeDom Klassen darstellen:
CodeVariableReferenceExpression für den Verweis auf die lokalen Variablen
CodeBinaryOperatorExpression für den Größer-Operator (a > b)
CodeConditionStatement für die if-Anweisung.

Thema: Punkt umkreisen (Winkel berechnung)
Am im Forum: Grafik und Sound

Nur als Ergänzung:
Mit Sinus, Kosinus und Tangens erhält man zu einem Winkel ein passendes Seitenverhältnis

sin(alpha)=Gegenkathete/Hypothenuse
cos(alpha)=Ankathete/Hypothenuse
tan(alpha)=Gegenkathete/Ankathete

Allerdings hast du ja gerade mit dy/dx das Seitenverhältnis, aber nicht den Winkel, den du suchst. Der Arkussinus/-kosinus/-tangens ist die Umkehrfunktion des Sinus/Kosinus/Tangens und berechnet somit zu einem Seitenverhältnis den passenden Winkel.
asin(Gegenkathete/Hypothenuse)=alpha
acos(Ankathete/Hypothenuse)=alpha
atan(Gegenkathete/Ankathete)=alpha

Thema: Punkt umkreisen (Winkel berechnung)
Am im Forum: Grafik und Sound

1) Die trigonometrischen Funktionen im .NET-Framework rechnen mit dem Bogenmaß. Eine Umdrehung (360°) entspricht im Bogenmaß 2*PI, was etwa 6,28 und somit ca. 6,3 ist.

2) Der Ansatz mit dem Dreieck sollte doch funktionieren. Der Winkel zwischen zwei Punkten ist (mithilfe eines Dreiecks leicht zu erkennen):

alpha = atan(dy/dx)
atan ist die Arcustangens-Funktion und dy bzw. dx ist die Differenz der y- bzw. x-Koordinaten deiner Punkte.

Thema: Unterschied zwischen i+=1 vs. i=i+1 bei Bytes
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Ergänzend zu der Antwort von Console32:
7.13.2 Compound assignment (C#)

Das Verhalten kann man als Compiler-Feature betrachten.

byte b = 0;
b += x;
// Wird zu b = (byte)(b + x);
Es funktioniert nur, wenn der der Compiler garantieren kann, dass x zu einem Byte konvertiert werden kann, ohne dass Daten verloren gehen. Dies ist der Fall, wenn x ein Integer-Literal kleiner als 256 ist oder x als konstanter Integer definiert wurde und kleiner als 256 ist. Interessanterweise ist eine long-Konstante kleiner als 256 nicht gültig.


byte b = 0;
int x1 = 100;
const int x2 = 100;
b += 100; // Geht
b += x2; // Geht
b += x1; // Geht nicht

Thema: Event in Form aus Klasse starten
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Zitat
Was mache ich denn jetzt noch falsch?

public static event KennwortDouble<EventNameEventArgs> OnKennwortDouble
muss heißen:

public static event EventHandler<EventNameEventArgs> OnKennwortDouble;

Events

Thema: Trotz Verwendung von CryptoStream stehen die Daten zusätzlich unverschlüsselt in der Datei
Am im Forum: Rund um die Programmierung

Zitat von dott
So funktioniert es jetzt, ist der code auch so in Ordnung oder gibt es was zu verbessern?

Ja, da ist einiges zu verbessern.
1) Entferne den StreamReader. Der wird in deinem Code nicht benutzt.
2) Pack den FileStream ebenfalls in eine using-Anweisung
3) Entferne cryptoStream.Close(), da using das bereits macht.

Dazu solltest du dir angucken, was die using-Anweisung überhaupt ist:
using-Anweisung

Thema: Trotz Verwendung von CryptoStream stehen die Daten zusätzlich unverschlüsselt in der Datei
Am im Forum: Rund um die Programmierung

Du schreibst das Objekt zwei Mal in die Datei:
1)


BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, this); // Unverschlüsselt über FileStream!!!

2)


byte[] byteData = new byte[Convert.ToInt32(fs.Length)];
cryptoStream.Write(byteData, 0, byteData.Length); // Wieder über den FileStream!
Außerdem scheint es mir so, als ob du ein leeres Byte-Array in die Datei schreibst?!

Eigentlich solltest du ja direkt über den CryptoStream serialisieren können:


FileStream fileStream = new FileStream(...);
CryptoStream cryptoStream = new CryptoStream(fileStream, ...);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(cryptoStream, this); // über den CryptoStream serialisiert

Thema: Erzeuge BindingList<T> aus typeof(T).GetElementType()
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Da muss ich herbivore zustimmen. Aus deinem Eingangspost ging für mich nicht hervor, dass noch ein Wert an die Methode übergeben wird. In diesem Fall ist es natürlich viel leichter einfach eine Überladung anzubieten, so wie es herbivore gezeigt hat.

Thema: Erzeuge BindingList<T> aus typeof(T).GetElementType()
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Per Reflection ist sowas möglich (frei aus den Kopf heraus):


void Foo<T>()
{
    Type type = typeof(T);
    if (type.IsArray)
    {
        Type elementType = type.GetElementType();
        Type bindingListType = typeof(BindingList<>);
        Type bindingListOfElementType = bindingListType.MakeGenericType(elementType);
        object bindingList = Activator.CreateInstance(bindingListOfElementType);
    }
}

Wenn es möglich ist, solltest du eine extra Methode für Arrays benutzen:


void FooArray<T>()
{
  BindingList<T> bindingList = new BindingList<T>();
}