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 gfoidl
Thema: Cancel Task / Soll immer nur ein Task laufen
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo BlueSubmarine,

Zitat
Es soll aber immer nur ein Task gleichzeitig laufen.
Das lässt sich i.d.R. durch andere Architekturen besser lösen, wie auch Abt erwähnt.
Z.B. mittels Channels lässt sich ein Producer/Consumer sehr effizient und einfach umsetzen.

Sollte die Anforderung dennoch "nur ein Task gleichzeitig" sein, so lässt sich das via eigenem TaskScheduler

Thema: MongoDB mit C# auslesen
Am im Forum: Datentechnologien

Hallo oehrle,

hast du dir die Fehlermeldung auch durchgelesen? V.a. die InnerException? Hier nochmal der Einfachheithalber:

Zitat
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. 10.38.143.27:27017
Ist also die DB erreichbar? Firewall, etc. gestattet den Zugriff? Kann z.B. via Robomongo auf die DB zugegriffen werden usw.

mfG Gü

Thema: MongoDB mit C# auslesen
Am im Forum: Datentechnologien

Hallo oehrle,

Zitat
tritt ein Fehler auf
Du bist ja nicht erst seit Kurzem beim Forum dabei und wohl auch als Entwickler tätig. Daher solltest du auch wissen dass "ein Fehler" eine sehr exakte Beschreibung vom Problem ist, bei der sich jeder sofort auskennt und zielgerichtet eine hilfreiche Antwort verfassen kann. Oder auch nicht...

mfG Gü

Thema: Zyan für .NET Core / Standard
Am im Forum: Netzwerktechnologien

Hallo Alf Ator,

gRPC.

Schau dir das einmal an, mehr schreib ich jetzt nicht ;-)

mfG Gü

Thema: Funktion für alle Objekte einer Klasse
Am im Forum: Grundlagen von C#

Hallo Jonas2909,

Zitat
Gibt es eine Möglichkeit eine Methode für alle Objekte aufzurufen?
Speichere alle Menschen in einer Liste, dann kannst du z.B. mit foreach über diese Liste iterieren und für jedes Menschen-Objekt die Methode aufrufen.


public class Welt
{
    private readonly List<Mensch> _menschen;

    public void BewegeAlleMenschen(/* ... */)
    {
        foreach (Mensch mensch in _menschen)
        {
            mensch.Bewege(/* ... */);
        }
    }
}


BTW: [Tipp] Anfängerhinweis == true / == false

mfG Gü

Thema: Erstellen von Workflows
Am im Forum: Rund um die Programmierung

Hallo C4RL0,

Zitat
Gibt es Frameworks ... die soetwas unterstützen ...
Ja gibt es, aber das hängt von den Rahmenbedingungen ab, also ob ein solcher Einsatz möglich ist od. nicht. Wegen
Zitat
I.d.R. arbeite ich mit Windows Forms.
gibt es irgendwelche Beschränkungen, Voraussetzungen, etc. die du uns mitteilen solltest? Z.B. es muss auf einem Server in eurer Firma laufen, kann in der Cloud sein, Clients sind alle WinForms od. nicht, Datenbank muss SQL Server sein od. nicht. Usw. denn danach richten sich auch die möglichen Empfehlungen / Tipps.

Nach "workflow engines" hast du sicher schon gegooglet ;-)

mfG Gü

Thema: Heute kommt .NET 7
Am im Forum: Szenenews

Hallo,

Zitat
Wobei ein Umstieg eigentlich kaum Probleme machen dürfte.
Für "normale" Anwendungen sollte es keine Problem geben, da wie immer sehr hoher Wert auf Abwärtskompatibilität gelegt wird / wurde. Ganz klappt das jedoch nicht immer, daher zeigt Breaking changes in .NET 7 eine Übersicht davon.
Zitat
Hat sich ggf. noch bei der Performance mit .NET 7 geändert oder läuft noch alles gleich flink?
.NET hat ein sehr intensives Perf-Lab indem fast permanent Benchmarks laufen um eventuelle Regressionen frühzeitig entdecken zu können.
.NET 7 ist in vielen Bereichen schneller als bisherige .NET-Versionen, zumindest jedenfalls nicht langsamer. Details dazu im Link, den Abt gepostet hat.

Wichtiger finde ich jedoch die Menge an neuen APIs und C#-Möglichkeiten, die es uns allen gestatten eleganteren / effizienteren Code zu schreiben :-)

mfG Gü

Thema: Grundsätzliche Verständnisfrage zu get und get
Am im Forum: Grundlagen von C#

Hallo Little Tester ,

Zitat
bekommen, also "get". Ich will die Variable dann nicht mehr verändern, weil ich ja die Information dann habe die ich brauche.
Das passt so und das Objekt ist dann "immutable", kann also nicht mehr verändert werden.
Die Werte der Eigenschaft kann im Konstruktor gesetzt werden.


public class Person
{
    public string Name { get; set; }
    public Date Birthdate { get; }

    public Person(string name, Date birthdate)
    {
        Name = name;
        Birthdate = birthdate;
    }
}
Name hat Getter und Setter, da sich der Name z.B. durch Heirat, Namensänderung ändern kann.
Birthdate kann sich aber nicht ändern, daher nur ein "Getter".
Um die Werte zu setzen, werden diese während der Konstruktion des Objects im sog. Konstruktor gesetzt.

mfG Gü

Thema: Fuzzing, WinDbg Preview (Store app) und Time Travel Debugging
Am im Forum: Smalltalk

Hallo dr4g0n76,

Fuzzing benutz ich bei Parsern die "untrusted input" haben und von byte / char -> T gehen.
Da kann es schon sein, dass ein paar Kombinationen der Bytes (im hohen UTF-8 Bereich) dabei sind, an dene ich bei Unit-Tests nicht gedacht habe. Durch das Ergebnis einer solches Fuzz-Session wenn etwas gefunden wurde, können die Unit-Tests nachgerüstet werden.

Ich seh Fuzzing dennoch eher als Nische und nur für spezielle Anforderungen, wie eben Parser, sinnvoll an.
Wobei mit "Parser" auch das Lesen einer Befehszeile, einer Konfig gemeint sein kann. Bei diesen Beispielen würde ich aber sowieso auf die .NET Infrastruktur aufbauen und vertrauen dass es passt (dort könnte Fuzzing wiederum angewandt werden).

Der Aufwand an sich um Fuzzing zum Laufen zu bringen ist nicht recht hoch, aber die Dauer einer Fuzz-Session i.d.R. schon (etliche Stunden und mehr).
Nur bei trivialen Bugs kann der Fuzzer recht schnell einen Treffer finden -- das ist aber stochastitisch und nicht deterministisch, je nachdem welche Seed für die Mutationen, etc. verwendet wird.

Also kurz: finde ich sinnvoll, aber nur für wenige spezielle Anforderungen.

WinDbg verwende ich nicht (direkt). Wenn schon dotnet-dump und den dortigen SOS Befehlen.

mfG Gü

Thema: Docker: SQL-Server als container - exec format error
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Hallo Palladin007,

Zitat
Ich will den hauptsächlich als Test-Server für Projekte nutzen, aktuell immer EFCore + SQLServer
Dazu nehm ich eine lokal gehostete Linux-VM (in VirtualBox), in welcher der SQL Server als Docker-Container läuft.
Der Container damit ein sehr einfaches Reset möglich ist.
Außerdem kann so ein vom SQL Server ein eigenes Image erstellt werden, das dann u.a. für CI verwendet wird.

mfG Gü

Thema: Übungsprogramm das kleine 1*1
Am im Forum: Grundlagen von C#

Hallo Biokartoffel,

Zitat
Damit öffnen sich gleich neue Ideen.
Daher gabs auch den Code, denn i.d.R. ist das Forum kein Code-Generator. Aber als Ansport / Einstieg kann und soll so ein Schnippsel dienen -- wir alle haben ja einaml begonnen ;-)

mfG Gü

Thema: Übungsprogramm das kleine 1*1
Am im Forum: Grundlagen von C#

Hallo Biokartoffel,

z.B.:


Random rnd = new();

Console.WriteLine("Übungsprogramm \"Kleines 1*1\". Abbruch mit Ctrl+C");
Console.WriteLine();

const int LowerInclusive = 0;
const int UpperInclusive = 10;

while (true)
{
    int a = rnd.Next(LowerInclusive, UpperInclusive + 1);
    int b = rnd.Next(LowerInclusive, UpperInclusive + 1);

    Console.Write($"{a} * {b} = ");
    string? answer = Console.ReadLine();

    if (answer is null)
    {
        break;
    }

    if (int.TryParse(answer, out int result))
    {
        int expected = a * b;
        bool isCorrect = result == expected;

        Console.Write("Antwort ist ");
        Console.ForegroundColor = isCorrect ? ConsoleColor.Green : ConsoleColor.Red;
        Console.WriteLine(isCorrect ? "richtig" : "falsch");
        Console.ResetColor();
    }
    else
    {
        Console.WriteLine("Falsche Eingabe, eine Zahl wird erwartet.");
    }
}

Das kannst du nun beliebig ausbauen :-)

mfG Gü

Thema: VS 2022 vergisst Einstellungen
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Hallo colophonius,

Zitat
Wenn ich ein Rep öffne
Öffnest du das in einen leeren Ordner?
Dann ist der .vs-Ordner ja auch nicht da.

Wenn ich mit Projekten öfter arbeite, so sind diese lokal vorhanden und ich brauch nur per Pull / Fetch die Änderungen holen. Die lokalen Einstellungen in .vs, .suo bleiben davon unberührt.

mfG Gü

Thema: VS 2022 vergisst Einstellungen
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Hallo colophonius,

Zitat
Wenn ich ein Rep öffne, muss ich jedesmal bestimmte Einstellungen erneut konfigurieren. Dazu zählen z. B. die Startprojekte.
Diese Benutzer-Einstellungen werden im .vs-Ordner im Wurzelverzeichnis des Repo gespeichert (is ein Hidden-Folder).
Dieser sollte auch nicht in die Versionskontrolle eingecheckt werden -- eben da "Benutzer-Einstellungen".
Wenn dieser beim Auschecken nicht vorhanden ist, so tritt eben das beschriebene Verhalten auf.

mfG Gü

Thema: Polynomkoeffizienten aus string in double[] parsen
Am im Forum: Grundlagen von C#

Hallo ThavalUga,

die Zeichenkette muss geparst werden, dabei gehts am einfachsten mit [Artikel] Regex-Tutorial, wie z.B. ^([+-]?(?:\d+)?)(x(?:\^(\d+))?)?. Wenn du damit nicht vertraut bist, so schauts schrecklich aus, aber wenn das selbst geschrieben wird gehts recht einfach, da für jede "Gruppe" die benötigt wird ein "Block" dasteht.

Schau dir mal im Code die Methode GetPolynomCoefficients an. Dort wird per Regex ein Term gematched, dieser dann geparst und die Eingabe um diesen Term verkürzt. Mit den restlichen Termen gehts dann so weiter, bis letztlich nichts mehr übrig ist.


using System.Text.RegularExpressions;

string input = "3x^4+2x^3-x^2+x-5";

double[] coefficients = GetPolynomCoefficients(input)
    .OrderByDescending(t => t.Power)
    .Select(t => t.Coefficient)
    .ToArray();

Console.WriteLine(input);
for (int i = 0; i < coefficients.Length; ++i)
{
    double c = coefficients[i];
    Console.Write($"{(Math.Sign(c) ≥ 0 ? "+" : "-")}{Math.Abs(c)}");

    if (i < coefficients.Length - 2)
    {
        Console.Write($"x^{coefficients.Length - 1 - i}");
    }
    else if (i < coefficients.Length - 1)
    {
        Console.Write("x");
    }
}
Console.WriteLine();

static IEnumerable<Term> GetPolynomCoefficients(string input)
{
    // language=regex
    const string Pattern = @"^([+-]?(?:\d+)?)(x(?:\^(\d+))?)?";

    while (input.Length > 0)
    {
        Match match = Regex.Match(input, Pattern);

        if (!match.Success)
        {
            throw new Exception("Given polynom can't be parsed. Bla bla bla (more info about failure and how to recover)");
        }

        if (!TryGetCoefficient(match, out double coefficient))
        {
            throw new Exception("... (something like 'coefficient can't be parsed at index ...')");
        }

        if (!TryGetPower(match, out int power))
        {
            throw new Exception("... (something like 'power can't be parsed at index ...')");
        }

        yield return new Term(coefficient, power);

        input = input[match.Length..];
    }

    static bool TryGetCoefficient(Match match, out double coefficient)
    {
        string value = match.Groups[1].Value;

        if (value.Length == 0 || value == "+")
        {
            coefficient = 1d;
            return true;
        }

        if (value == "-")
        {
            coefficient = -1d;
            return true;
        }

        return double.TryParse(value, out coefficient);
    }

    static bool TryGetPower(Match match, out int power)
    {
        string value = match.Groups[3].Value;

        if (value.Length == 0)
        {
            if (match.Groups[2].Value.Length == 0)
            {
                power = 0;
                return true;
            }

            if (match.Groups[2].Value == "x")
            {
                power = 1;
                return true;
            }
        }

        return int.TryParse(value, out power);
    }
}

public readonly record struct Term(double Coefficient, int Power);

Ohne Regex ginge es auch, aber aufgrund der Sonderfälle wie implizit {+1, -1} als Koeffizient wird schon umständlicher. Genauso wenn die Potenz implizit {1, 0} ist.
D.h. ohne Regex würde eine Art Syntax-Baum benötigt werden und das ist wohl Overkill. BTW: das Regex-Match kann hier als Art "Mini-Syntax-Baum" gesehen werden.

mfG Gü

Thema: Schichten-Trennung bei 3 Schichten
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo kstanger,

bei dem Thema wo es ums Verständnis geht helfen vllt. mehre Antworten mit ähnlichem Inhalt, aber verschiedenem Text ;-)

Der Vollständigkeithalber: [Artikel] Drei-Schichten-Architektur

Einfache Pauschalantworten auf deinen Frage kann ich nicht geben, da es wie so oft abhängt, worum es konkret geht. Ich versuch daher verkürzt und vereinfacht zu antworten.

Zitat
Wie trennt man eigentlich die 3 Schichten?
Bei kleinen Projekten: verschiedene Namespaces
Umso größer das Projekt wird, so desto eher erfolgt auch eine Aufteilung in verschiedene Projektmappen (csproj).
Möglichkeiten gibt es viele, die aber vom konkreten Fall abhängen.
Zitat
Und wie verbindet man sie? z.B. über Methodenaufrufe?
Wenn alles im gleichen Prozess läuft, dann ja. Einfacher und besser geht es nicht.
Sind die Schichten über mehrere Prozesse verteilt, so wird IPC (inter process communication) benötigt und falls die Schichten gar auf mehreren Servern verteilt sind, dann eine andere Kommunikationsart.
Zitat
über das Modell spricht, nicht aber über die Umsetzung.
Ich sehe dafür merhere Gründe (auch wenn ich zurück an meine Anfangszeiten denke):
  • Es gibt nicht "die Umsetzung" da es je nach konkreter Anforderung verschiedene Ausprägungen geben kann. Sowie es in der (Bau-) Architektur auch nicht "die Umsetzung" vom Haus gibt. Grundsätzlich schon (Keller, Parterre, Obergeschoße), aber konkrete hängt es auch hier vom Anwendungsfall ab.

  • Die 3-Schichten Architektur ist trivial -- da gibt es nicht sehr viel zu beschreiben.
    Mir gings aber auch so, dass die geistige Hürde fürs Verständnis erst einmal übersprungen werden musste. Am einfachsten gehts mit einem ganz simplen Projekt, bei dem Unit-Tests vorhanden sind, denn die Testbarkeit von Komponenten führe mehr od. weniger automatisch zum richtigen Design.
Zitat
Datenzugriffsschicht = Definition der Objektlisten + Serialisierung
"Serialisierung" für was? Nimm besser ein Datenbank statt in Dateien zu Serialisieren.

mfG Gü

Thema: Asp.Net Anwendung - Azure File Storage
Am im Forum: Web-Technologien

Hallo Savage,

warum verwendest du keinen Blog-Storage und greifst über den zugehörigen Client / SDK darauf zu?
Dann wäre das auch sauber getrennt und zukunftssicherer, falls die Anwendung z.B. auf serverless geändert werden sollte, etc.

Im Code jedenfalls sollte das Verwalten der Dateien ohnehin wegabstrahiert worden sein, dann sind solche Änderungen auch recht einfach durchführbar.

mfG Gü

Thema: Namensliste in csv-Datei Vornamen alphabetisch sortieren
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo shutouke,

Zitat
Ich schreibe gerade ein Programm das mich an Geburtstage erinnern soll.
Statt einer CSV kannst du dafür auch eine "richtige" Datenbank verwenden. Es gibt auch Datenbanken die ohne Server auskommen (z.b. SQLite).
Dann brauchst du dich ums Sortieren beim Einfügen nicht kümmern und kann die Prüfung auf Geburtstag recht einfach per Abfrage gegen die DB durchführen.

Wenns um den Lerneffekt geht, so mach beide Varianten: CSV und DB. Da lernst du viel und kannst selbst über die Vor-/Nachteile jeder Variante sinnieren.

mfG Gü

Thema: Hashcode von Strings
Am im Forum: Grundlagen von C#

Hallo Tommix,

der HashCode ist kein kryptografischer Hash des Strings (gilt für Object im Allgemeinen), sondern nur eine Art "Fingerabdruck" für den aktuellen Prozess, so dass Vergleiche und v.a. Hash-basierte Datentypen (wie Dictionary, HashSet) mit O(1)-Operationen umgesetzt werden können.

Bei int ist der HashCode trivial implementiert, nämlich der Wert einfach selbst.

Da GetHashCode als Rückgabetype int verwendet gibt es folglich auch nur soviele verschiedene HashCodes wie eben mit int abgebildet werden können (2^32 = 4.294.967.296). Also eine begrenzte Menge und das Schubfachprinzip findet Anwendung, kurz es wird Kollisionen (= gleicher HashCode) geben.

Strings sind wohl einer am häufigst verwendeten Datentypen. Web-Server und Authentifizierungserver sind hierbei keine Aussnahme.
Würde für jeden Programmablauf für den gleichen String immer der gleiche HashCode ermittelt werden, so öffnet das die Tür für Angriffe* da ein bestimmter String eine deterministische Ausgabe (hier HashCode) liefert.

Aus diesem Grund verwendet .NET seit einiger Zeit (ich glaube .NET Core 2.1, habs nicht nachgeschaut) einen zufälligen "Startwert" für String-Hashes. D.h. innerhalb eines Programmablaufs ist das Resultat von GetHashCode für gleiche Eingaben deterministisch (sonst wäre es ja unsinnig), aber für jeden Programmablauf eben anders um solche Angriiffe zu erschweren.

Wie eingangs bereits angedeutet sollte der Wert von GetHashCode ohnehin nicht von Bedeutung sein und v.a. nicht explizit verwendet werden, denn dazu ist GetHashCode nicht gedacht. Betrachte den Wert von GetHashCode als Implementierungsdetail, das für Dictionary, HashSet, EqualityComparer, etc. verwendet wird ohne dass du dich für den tatsächlichen Wert interessierst**.

* auf dem Gebiet kenn ich mich zu wenig aus um konkrete Beispiel liefern zu können.
** außer du entwickelst eine eigene Methode für GetHashCode von eigenen Typen um so eine möglichst gleichmäßige Verteiliung ohne zuviele Kollisionen zu erhalten

mfG Gü

Thema: Ich habe noch immer mit den .NET Core Nachfolgern Probleme
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Hallo theuserbl,

Zitat
Das fühlt sich an wie Visual Studio - nur ohne GUI:
;-)
VS verwendet (mehr od. weniger) die gleichen Build-Tools, daher ist deine Aussage schon korrekt.
Zitat
- Im Projekt-Order wird eine Visual Studio Projektdatei (MyApp.csproj) angelegt.
- Die Binaries entstehen nicht standardmäßig wie beim alten .NET FRamework, C/C++ und Java an der Stelle, wo auch der Quellcode ist, sondern es werdem - wie bei VisualStudio - Unterordner "bin" und "obj" erstellt, die ihrerseits jeweils entweder einen Unterordner "Debug" oder "Release" haben, wo dann die Binärdateien enthalten sind.
Dass das Kompilat im gleichen Ordner landet wie die Quell-Dateien ist ein Anti-Pattern und sollte ohnehin vermieden werden.
Die Unterscheidung zwischen Debug / Release macht auch Sinn, da es dem Compiler frei steht für Release mehr Optimierungen durchzuführen.

Gängige Build-Tools anderer Sprachen / Plattformen wie z.B. CMake (hauptsächlich für C/C++) verhalten sich hier nicht anders. Statt der csproj gibt es eine / mehrere CMakeList.txt und die Ausgabe erfolgt auch in einem von der Quelle unterschiedlichen Pfad.

MsBuild (das Tool welches die csproj verarbeitet) muss du ja nicht verwenden, sondern kannst auch direkt mit CSC arbeiten. Aber ohne Build-Script (welches csproj letztlich auch ist) wird es eher schnell unhandlich.
Mit und ohne csproj kann der Ausgabe-Pfad auch konfiguriert werden -- standardmäßig werden halt Defaults verwendet, die sich in .NET so eingebürgert haben.
Zitat
So ist ja das Anfangs C#-Programm eins, das eher wie aus einer Skriptsprache aussieht: Ohne Main-Methode und Klasse direkt mit dem Befehl losgelegt.
Zumindest in der VS-Projektvorlage kann die "alte Verhalten" mit class Program und static void Main wiederhergestellt werden.
Aber ich finds ohne netter, denn wozu immer wieder den unnötigen Code (generieren lassen). Der bläht ja nur auf ohne wirklichen nutzen.

Dass es aussieht wie eine Skriptsprache war in der Tat eine der Motivationen hinter dieser Änderung, denn für Einsteiger wurde es als unnötige Hürde erachtet eine Klasse und eine statische Methode zu erstellen, welche als Einstieg (ins Programm) dienen.
Wie T-Virus erwähnt ist das aber nur Compiler-Magick

mfG Gü

Thema: Ich habe noch immer mit den .NET Core Nachfolgern Probleme
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Hallo,

Zitat
Da ich es nicht installieren möchte, lade ich für Windows eine zip-Datei runter.
Der Installer wird ja gerade destwegen angeboten, damit die Pfade, etc. nicht manuell gesetzt werden müssen.
Mit dem zip (ala xcopy-Deploy) kann eine bestehende Installation überschrieben werden od. man erfüllt die nötigen Vor- und Nachschritte selbst. Das ist so aber auch dokumentiert -- siehe Download and manually install.

Bitte immer Dokus lesen bevor die Schuld auf eine Technologie geschoben wird!
Zitat
Kein csc.exe und kein vbc.exe .
Auch in den Unterverzeichnisssen finde ich keine Compiler.
In .NET ist seit jeher die Assembly das Binär-Produkt. Beim .NET Framework wurde eine EXE erzeugt, die im Grunde nichts anderes als der Code gepackt als DLL und zusätzlich der Loader-Teil für das Betriebssystem ist. Damit das OS das auch verwenden kann wurde es als nur als EXE "verpackt".

In .NET Core und später .NET wurde nur eine DLL erzeugt*, welche mittels dotnet MeineAnwendung.dll gestartet werden kann. dotnet ist dabei der Host und enthält u.a. den Loader-Teil fürs OS.

Im Ordner .\dotnet-sdk-7.0.100-preview.7.22377.5-win-x64.zip\sdk\7.0.100-preview.7.22377.5\Roslyn\bincore sind nun die Compiler tatsächlich vorhanden ;-)
Aber nicht als EXE, sondern als csc.dll (C# Compiler) und vbc.dll (VB.NET Compiler).
Wie vorhin erwähnt, können diese via dotnet csc.dll ausgeführt werden. I.d.R. jedoch via MsBuild-Task der die Assembly lädt und direkt ausführt**.

* bei einem Framework-dependent deployment, es gibt auch weitere Möglichkeiten bei denen eine EXE direkt erstellt wird, aber das lässt sich in der Doku nachlesen

** ein wenig kompliziertes ist es mittlerweile schon, da zur Leistungssteigerung und für den Gebrauch in VS eine Art Build-Server gestartet wird, der den / die Compiler-Instanzen verwaltet
Zitat
WTF??? Geht es noch komplizierter?

Ok, ich habe nun also aus dem Unterverzeichnis .\shared\Microsoft.NETCore.App die Datei hostpolicy.dll ins Hauptverzeichnis kopiert.
Obs noch komplizierter geht weiß ich nicht, aber du bist schon ganz gut dabei ;-)

Mit einem Blick in die Doku (siehe oben) od. durch Verwendung des Installers hättest du weniger Frust und die Zeit, welche für deinen Beitrag hier benötigt wurde, hätte in Produktives umgesetzt werden können.
Zitat
Muß man nun für jede exe-Datei zusätzlich eine json-Datei erstellen?
Beim .NET Framework war es nicht nötig.
Nein. Zum Einen geschieht dies automatisch durch die Build-Tools, zum Anderen werden diese json-Dateien bei Single-File-Deployment ebenfalls in die EXE gepackt.
.NET Framework funktioniert z.T. anders und v.a. nicht auf anderen OS als Windows. Daher sind auch andere Konzepte nötig um wirklich plattformunabhängig sein zu können.

Betrachte diese json-Dateien einfach als Teil der Build-Ausgabe. Diese stören doch nicht? Falls es es dich stört und du nur eine EXE als Ausgabe haben willst, so schau dir Single-file deployment and executable an.

mfG Gü

Thema: Min() zweier Gleitkommazahlen zurückgeben
Am im Forum: Grundlagen von C#

Hallo Sw4t,

für Komplettheit: Math.Min ist eine Methode in .NET für das Minimum von 2 Werten.

mfG Gü

Thema: StreamWrapper zum Limitieren der Position und Length
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo sandreas,

ich finde die StreamLimiter Klasse ist weder Teig noch Mehl. Irgendwie wird der _innerStream beschränkt, dann aber doch nicht so ganz konsequent.
Z.B. Position gibt diese vom _innerStream an.

So einen Typen würde ich eher SubReadStream nennen, der eine "View" über den _innerStream legt, dabei zu Beginn von Außen Offset := 0 und Länge := das Limit ist.
Intern kann das ja auf den _innerStream umgerechnet werden. Z.B. beim Setzen der Position halt den Offset berücksichtigen.

Beim Lesen, egal ob die byte[] od. Span<byte>-Überladung, ist count bzw. der buffer (bei Span-Überladung) entsprechend zu verkleinern, falls über das Limit hinaus gelesen würde.

Für den Verwender sollte dieser Stream jedenfalls nur den nutzbaren Teil (~ "View") widerspiegeln.

mfG Gü

Thema: StreamWrapper zum Limitieren der Position und Length
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo sandreas,

Zitat
Man kann da bestimmt wieder einiges falsch machen, wenn man die interna von Stream nicht genau kennt.
Warum? Es ist hier doch nur einfache Addition (wieviel schon gelesen wurde) und ein Vergleich mit der Soll-Länge?! KISS -- vermutlich hast du dich gedanklich in einem zu komplizierten Weg verrannt.

Die Interna von Stream (der Basisklasse) sind nicht sehr schwierig, v.a. bei Read. Man übergibt einen Buffer (optional wenns ein byte[] ist auch Offset und Count) und teilt somit mit, wieviel max. gelesen werden soll. Als Rückgabewert kommen die Anzahl der gelesenen Bytes. Mehr ist es nicht -- das macht das Konzept vom Stream so universal einsetzbar (sowas finde ich ganz einfach super).

Ob der tatsächliche Stream ein FileStream, NetworkStream, etc. ist spielt dabei keine Rolle. Für die Verwendung vom Stream braucht man auch nicht* wissen wie NetworkStream unter der Haube funktioniert, da in .NET das Liskovsches Substitutionsprinzip befolgt wird.

* es schadet aber nicht ;-)

Zitat
gibt es schon fertig bei nuget
Kann sein. Aber bei "trivial Aufgaben" ist der Aufwand bei NuGet oft höhere, da
  • Suchen ob es etwas gibt
  • wenns mehrere gibt evaluieren was am besten passt
  • mind. ReadMe lesen / Doku lesen
Zusätzlich hier noch das Thema im Forum -- in dieser Zeit wäre die Lösung inkl. Tests wohl schon fertig ;-)


mfG Gü

Thema: Backtracking Knight Problem
Am im Forum: Rund um die Programmierung

Hallo RedByte, willkommen im Forum!

Zitat
Bitte nur konstruktive Rückmeldungen
Konstruktive Rückmeldungen beginnen schon mit der Frage und wie einfach es potentiellen Helfern gemacht wird.
Dazu zähle ich "hab ein Problem, Code ist auf PasteBin, schau ihn dir an" nicht unbedingt. [Hinweis] Wie poste ich richtig?
Wo hängst du genau? Hast du mit dem Debugger schon versucht den Programmablauf zu verfolgen?
Lässt sich das Problem durch ein einfacheres ersetzen (z.B. nur 2x2 Felder) und funktioniert dort der Algorithmus?

mfG Gü

Thema: StreamWrapper zum Limitieren der Position und Length
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo sandreas,

ganz verstehe ich das Problem nicht bzw. warum soviel drumherum diskutiert wird.
Schreib einen Stream-Wrapper, dessen Ctor Offset und Länge auch übergeben wird, und das Problem ist gelöst.

Per Definition der Stream.Read-APIs wird maximal count Bytes gelesen, d.h. es kann weniger sein. Falls nichts mehr zu lesen ist, so wird 0 zurückgegeben.
Damit lässt sich das Problem fast trivial lösen.

mfG Gü

Thema: C# Projekt unter IIS zum Laufen bringen
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Hallo Bronstein,

was mich wunder -- bei der Fehlermeldung -- warum Out-Of-Process steht, da ist nirgends konfiguriert (od. ist das der Standard, weiß ich nicht).
In der Projektdatei (csproj) und der web.config sollten die HostingModels ident sein.

D.h. entweder


<!-- csproj --> 
<PropertyGroup>
    <AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
</PropertyGroup>

<!-- web.config -->
<aspNetCore processPath ="dotnet"
            arguments   =".\test.dll"
            hostingModel="outofprocess">
<!-- ... ->
oder

<!-- csproj --> 
<PropertyGroup>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>

<!-- web.config -->
<aspNetCore processPath ="dotnet"
            arguments   =".\test.dll"
            hostingModel="inprocess">
<!-- ... ->

Probier dies einmal explizit zu setzen und schau dir die Fehlermeldung -- die hoffentlich nicht mehr kommt ;-) -- genau an.

mfG Gü

Thema: C# Projekt unter IIS zum Laufen bringen
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Hallo Bronstein,

hast du auch das Hosting Bundle (x86) installiert?
Sehe das nicht im Screenshot. Ohne dem, wegen ASP.NET Core Module v2, kann der IIS nicht mit ASP.NET Core kommunizieren.

mfG Gü

Thema: C# Projekt unter IIS zum Laufen bringen
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Hallo Bronstein,

Zitat
Da ich eine 32Bit DLL verwende habe ich im IIS Application Pool 32bit auf true gesetzt
...
Fehler
HTTP Error 502.5 - ANCM Out-Of-Process Startup Failure
Das ASP.NET Core Hosting Bundle, in dem das ASP.NET Core Module (ANCM) enthalten ist, muss auch als 32bit-Variante vorhanden / installiert werden.

Ich tippe mal dass du die 64bit-Variante installiert hast, denn darauf deuten die Fehlermeldungen hin.

mfG Gü

Thema: C# 8 Nullable reference types - Pro & Con
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo Palladin007,

in einer streng typisierten Programmiersprache gibt es keinen Grund NRTs nicht zu verwenden.

NRTs sind Teil vom Typsystem (während der Entwurfszeit) bzw. eine Erweiterung / Ergänzung dessen.
Etwas überspitzt: diese nicht zu verwenden wäre wie alle Argumente mit dynamic* antatt konkreter Typen zu schreiben. Oder eine untypisierte zu verwenden...

Wer also Typsicherheit haben will, sollte auch NRTs verwenden. Am besten mit <TreatWarningsAsErrors>true</TreatWarningsAsErrors> in den Projekteigenschaften.

* Laufzeitverhalten außer Acht gelassen, denn dynamic ist langsam

Zitat
So betrachtet ist es besser, dass es in eine NullReferenceException rennt, sofort auffällt und dann auch leicht(er) zu finden ist, als ein Logik-Fehler.
Hier liegt mMn bei vielen ein Verständnisfehler vor.
NRT sind eine Annotation, die zur Entwurfszeit via Compiler eine Hilfe gibt.
Das Laufzeitverhalten wird dadurch nicht beeinflusst. D.h. zur Laufzeit sind (bei öffentlichen / public APIs) daher sehr wohl Null-Prüfungen durchzuführen.
Siehe z.B. auch eine Diskussion im dotnet-docs Repo (und die Kommentare darunter) dazu.

Der große Vorteil von NRTs ist, dass der Compiler durch statische Analyse prüfen kann ob null zulässig ist od. nicht.

Da eben public APIs dennoch auf Null geprüft werden sollen, findet der große Vorteil bei internen APIs Anwendung. "Intern" ist hier nicht nur auf die internal, private, etc. (also alles außer public) begrenzt, sondern kann auch eine public-Methode sein, die nur innerhalb einer Anwendung / einer Organisation verwendet wird.
Anders gesagt: wenn nicht public im Sinne von "Verwendung für alle" sein soll, so können die Null-Checks auch entfallen falls die statische Prüfung vom Compiler ausreicht -- ergänzt (natürlich) mit Unit-Tests.

Auch public APIs profitieren von NRTs, da so via Methoden-Signatur ersichtlich ist ob null erlaubt ist od. ob bei (falscher) Übergabe von null eine NRE (besser: ArgumentNullException von der Validierung) geschmissen wird. D.h.


public int Foo(object? obj)
{
    // null kann für obj übergeben werden, die Implementierung hier muss damit umgehen können

    return obj is null 
        ? 0
        : obj.GetHashCode();
}

public int Bar(object obj)
{
    // null ist nicht gestattet, daher sollte das Argument validiert werden
    ArgumentNullException.ThrowIfNull(obj);

    return obj.GetHashCode();
}

internal int Baz(object obj)
{
    // null ist nicht gestatt, es ist ein kein öffentliches API, daher reicht eine Debug-Prüfung aus
    Debug.Assert(obj is not null);

    return obj.GetHashCode();
}

Auch sind die weiteren Annotation wie [NotNullWhen], etc. sehr hilfreich v.a. im Zusammenhang mit Try-Patterns, da so der Compiler im Zuge des "control flows" weiß wann der Wert null ist od. nicht.
Das hilft einfach Fehler zu vermeiden. Und zwar nicht erst bei Tests od. noch später, sondern während des Schreibens vom Code. Und es ist hinlänglich bekannt, je früher ein Fehler erkannt / behoben wird, desto weniger Kosten wurden dadurch verursacht.
Zitat
Man sollte einfach pauschal immer davon ausgehen, dass es null sein kann und entsprechend darauf prüfen.
Ergänzend zu Abts Kommentar dazu, dem ich zustimme, noch folgendes Analogon: bei Werttypen kann auch einfach default verwendet werden, aber prüft jemand ob der Wert default ist od. nicht?
Ja, der Vergleich hinkt und es gibt auch Nullable-ValueTypes, aber der Kern der Aussage ist: durch Annotationen und Asserts lassen sich zur Entwurfszeit viele Fehler vermeiden ohne dass zur Laufzeit alles geprüft werden muss / braucht. Unit-Tests erledigen den Rest.
Zitat
Wenn ein Entwickler vom Compiler darauf hingewiesen wird, auf null zu prüfen, dann setzt der ggf. ein sinnloses Default-Verhalten (oder Werte) um, die dann erst irgendwann später als Logik-Fehler auffallen.
Dann liegt das Problem aber zwischen Bildschirm und Bürostuhl ;-)
Zitat
... die dann erst irgendwann später als Logik-Fehler auffallen.
Das sollte doch bei Unit-Tests schon auffallen. Spätestens bei Integrations-Tests müsste das bemerkt werken -- idealerweise durch CI.
Wobei der Compiler nicht darauf hinweist "auf null zu prüfen", sondern der Compiler weist darauf hin, dass der Wert unerlaubterweise null ist.
Zitat von Abt
NullReferenceExceptions sind _immer_ Entwicklungsfehler.
-- auch wenn "fail early" gut ist, sind NREs einfach Bugs die durch Tests detektiert werden sollten bevor ein Produkt veröffentlicht wird.


mfG Gü