Laden...
T
tomschrot
myCSharp.de - Member
15
Themen
73
Beiträge
Letzte Aktivität
vor 8 Monaten
Dabei seit
26.08.2004
Alter
62
Beruf
Softwareentwickler
Herkunft
Herrsching a. A.
Erstellt vor einem Jahr

@Abt: Wenn das alles so doof ist, frage ich mich, warum das dann in C# eingebaut wird? Das C# Team bei MS ist ziemlich konservativ und neuer Syntax kommt nur in kleinen Dosen. Die wissen schon ziemlich genau, was sie tun.

Die NULL Operatoren sind schon sinnvoll, wenn sie richtig eingesetzt werden. Außerdem unterscheidet der Compiler genau zwischen NULLABLE und NOT NULLABLE Code. Dazu enthält csproj <Nullable>enable</Nullable> oder im Code #pragma nullable enable / disable / restore.

Erstellt vor einem Jahr

@BlonderHans: ja klar, damit MoveNext() nach Reset() aufs 1 (!!!) Element zeigt:

Das Iterator-Pattern verwendet eine Annehmende-Schleife:

        var enumerator = collection?.GetEnumerator ();
        enumerator?.Reset();
        
        while ( enumerator?.MoveNext() ?? false )
        {
            var value = enumerator.Current;
            ...
        }
Erstellt vor einem Jahr

Ein IEnumerable<T> definiert einen Typ der lediglich eine Funktion enthält, nämlich GetEnumerator() und liefert ein Objekt vom Typ IEnumerator<T>.

Ein IEnumerator<T> ist ein Typ der eine Eigenschaft sowie 2 Methoden enthält:

  • T Current: liefert einen Wert vom Typen T
  • bool MoveNext(): bewegt einen internen Index auf das nächste Element, liefert TRUE solange es Elemente gibt.
  • void Reset(): setzt den Index aufs 1. Element

Dies ist in .NET eine ziemlich geradlinige Implementation des Iterator-Patterns.

Jede Klasse, die einen IEnumerable implementiert, kann in C# mittel der foreach-Schleife iteriert werden. Das ist praktisch, um die Kapselung interner Datenstrukturen/Listen vor dem Konsumenten zu verbergen und entspricht dem Paradigma des "Information Hiding".

p.s. dein Beispiel oben kann nicht funktionieren, da Reset() VOR der While-Schleife stehen muss!

Erstellt vor einem Jahr

Hallo

Ich hab mal eine Infrastruktur-Klasse erstellt die die oben behandelte Fragestellung erledigt.

Die Klasse ist universell, sprich, kann auf jeden Registry-Key angewendet werden. Zum Spaß hab ich noch eine Funktion zugefügt, die über alle Einträge eines Keys läuft und die Werte dazu liefert. Die Klasse unterstützt Fluent-API und Funktionen höherer Ordnung und kann wie folgt genutzt werden: (ich hab statt IPV6 mal die Hardware abgefragt 😉

Listing Consumer:

const string
    IPV6    = @"SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters",
    IPCOMP  = "DisabledComponents",

    MYPC        = @"SYSTEM\HardwareConfig\Current",
    MAINBOARD   = @"BaseBoardManufacturer"
    ;

RegistryState
.ForKey  (MYPC)
.ValueOf (MAINBOARD, value => WriteLine (value))
.Values  ((@this, name) =>
{
    WriteLine ($"Key: {name} = {@this.ValueOf(name).ToString()}");
})
;

Listing Klasse:


using Microsoft.Win32;

namespace MyApp;

public sealed class RegistryState
{
    //-------------------------------------------------------------------------
    // Static Members
    //-------------------------------------------------------------------------

    public static RegistryState ForKey (string keyName) => new (keyName);
    //-------------------------------------------------------------------------

    #pragma warning disable CA1416
    private static RegistryKey readKey (string keyName)
    =>
        RegistryKey
        .OpenBaseKey (RegistryHive.LocalMachine, RegistryView.Registry64)
        .OpenSubKey  (keyName);
    //-------------------------------------------------------------------------
    // Instance Members
    //-------------------------------------------------------------------------

    public RegistryKey RegKey {get; private set;}
    //-------------------------------------------------------------------------

    private RegistryState (string keyName) => RegKey = readKey (keyName);
    //-------------------------------------------------------------------------

    #pragma warning disable CA1416
    public RegistryState Values (Action<RegistryState, string> emit)
    {
        iterate (RegKey?.GetValueNames(), emit);
        return this;
    }
    //-------------------------------------------------------------------------

    private void iterate (string[] items, Action<RegistryState, string> emit)
    {
        var enumerator = items?.GetEnumerator();

        while ( enumerator?.MoveNext() ?? false )
            emit (this, (string)enumerator.Current);
    }
    //-------------------------------------------------------------------------
    #pragma warning disable CA1416
    public object ValueOf (string name) => RegKey?.GetValue(name);

    #pragma warning disable CA1416
    public RegistryState ValueOf (string name, Action<object> emit)
    {
        emit ( ValueOf(name) );
        return this;
    }
    //-------------------------------------------------------------------------
}

Gruß,

Tom

Erstellt vor einem Jahr

Na ja,

es gibt schon einige Regeln um Code sauber zu strukturieren.

  • Clean Code
  • Domain Design
  • immer wieder gerne Design Patterns
  • und schließlich Functional Programming
  • mit Funktoren und Monaden

(aufsteigend nach Schwierigkeit geordnet 😉)

und zu guter Letzt, eine ordentliche Portion Erfahrung, welche sich, zugegeben, halt nur im Laufe der Jahre ergibt.

Es ist immer gut, sich mit "alten Hasen" auszutauschen und offen zu sein wie die's machen.

Erstellt vor 2 Jahren

Hallo

Ich habe mir eine Wear OS Smartwatch gegönnt die ich für 2 ganz konkrete Aktivitäten brauche (Segeln & Motorradfahren).
Leider ist die App-Landschaft doch recht übersichtlich, also hab ich mir gedacht, ich kann mir es ja selber programmieren...
(bin ein sehr erfahrener .NET Entwickler mit 20+ Jahre C#)

Mit Xamarin geht das auf VS doch relativ problemlos, auf den ersten Blick. (zumindest im Emulator)

Jetzt die Frage: wer hat evtl. schon Wear OS Erfahrungen und / oder Lust an einem kleinen C# Projekt mit zu arbeiten?
Zu sehen wäre das als ein Lernprojekt, nicht kommerziell, Codebasis via Github.

Erstellt vor 2 Jahren

using System;
using System.Collections.Generic;
using static System.Console;

List<Tier> tiere = new ()
{
	new Katze { name = "Freddy" },
	new Katze { name = "Fibi"   },
	new Hund  { name = "Bello"  },
	new Katze { name = "Isi"    },
	new Hund  { name = "Happy"  },
};

foreach (var tier in tiere)
{
	var prefix = tier switch
	{
		Katze => "Die Katze sagt ",
		Hund  => "Der Hund macht ",
		_	  => ""
	};
	
	WriteLine ($"{prefix} {tier.sprich()}");
}

WriteLine (DateTime.Now);

interface Tier
{ 
	string name {get;set;}
	string sprich();
}

class Katze: Tier
{
	public string name {get;set;}
	public string sprich() => "miau";
}

class Hund : Tier
{
	public string name {get;set;}
	public string sprich() => "wau wau";
}

https://dotnetfiddle.net/ZBMNTX

Erstellt vor 3 Jahren

Kampf dem Spaghetti Code.
Ich schlage Clean Code mäßig vor die Schreibweise mit Umbrüchen Zeilenweise zu verwenden.
Die Lesbarkeit ist besser und via Kommentare können einfach Änderungen vorgenommen werden.
(vertikalen Platz gibts ja genug...)



public readonly string softwareSysteminventoryVersion  = // for property use =>
        Assembly
        ?.GetExecutingAssembly()
        ?.GetName()
        ?.Version
        ?.ToString() 
        ?? String.Empty
        // "Version not defined!"
        ;


Erstellt vor 3 Jahren

Hi

kann das sein, dass diese Frage auf FB auch schon gestellt wurde?
Ich würde das so schreiben (.NET 6, C# 10):


using static System.Console;

const string DATAFILE =".\\my.data";

byte[] data =
{
    32, 32, 67, 67, 32, 32, 32, 35, 32, 35, 32,
    32, 67, 32, 32, 67, 32, 32, 35, 32, 35, 32,
    67, 32, 32, 32, 32, 32, 35, 35, 35, 35, 35,
    67, 32, 32, 32, 32, 32, 32, 35, 32, 35, 32,
    67, 32, 32, 32, 32, 32, 35, 35, 35, 35, 35,
    32, 67, 32, 32, 67, 32, 32, 35, 32, 35, 32,
    32, 32, 67, 67, 32, 32, 32, 35, 32, 35, 32
};

File.WriteAllBytes (DATAFILE, data);

var buf =   File.Exists (DATAFILE)
            ? File.ReadAllBytes (DATAFILE)
            : new byte[]{};

int count = 0;
foreach (var value in buf)
{
    Write ($"{value,2},");
    if (++count % 11 == 0) WriteLine ();
}

WriteLine ($"\r\nOK @ {DateTime.Now}");

Erstellt vor 3 Jahren

Hallo echdeneth

Gemäß UML ist das nicht so wild (obwohl ich persönlich das etwas anders lösen würde, aber okay...).

Die ObserveableCollection ist ein fester Bestandteil der Warenkorb Klasse, und somit als NUR LESEND zu setzen!
Also


public readonly ObservableCollection<Innentür> innentuerliste = new (); *

*kommt drauf an welche C# Version ihr benutzt...

Dekor ist nach UML keine Liste sondern eine Eigenschaft. Das drückt die Zahl 1 am Pfeil aus, es ist nur 1 Element.

Fragt sich, ob Dekor als NULL zu interpretieren ist wenn nicht benötigt, oder leere Standardwerte (besser)?