Laden...

Datenkapselung mit Arrays

Erstellt von Jonas007 vor 2 Jahren Letzter Beitrag vor 2 Jahren 492 Views
J
Jonas007 Themenstarter:in
37 Beiträge seit 2020
vor 2 Jahren
Datenkapselung mit Arrays

Hallo liebe Community,
ich habe folgendes Problem:
Innerhalb einer Klasse ist Array, auf welches man per Eigenschaftsmethoden zugreifen kann. Jedes mal, wenn sich etwas in dem Array ändert, möchte ich etwas bestimmtes ausführen.
Schematischer Code (ich hoffe, ihr versteht, was ich versuche):


class Test
{
    private string[] array = new string[] { "Element 1", "Element 2", "Element 3" };
    public string[] Array 
    { 
        get => array; 
        set
        {
            array = value;
            Console.WriteLine("Set Array...");        
        }
    }
}
class Program
{
    static void Main(string[] args)
    {
        Test test = new Test();
        test.Array[1] = "Ersetze dieses Element";
    }
}

Leider komme ich mit meinem Ansatz nie in den Set - Block der Klasse Test, da das Array ansich ja nicht neu gesetzt wird sondern nur innerhalb des Arrays ein Wert geändert wird.
Hat hier jemand evtl. eine Lösung?

Danke schonmal im voraus!
LG Jonas

2.078 Beiträge seit 2012
vor 2 Jahren

Warum nicht einfach eine SetArrayItem-Methode?
Alternativ kannst Du ein eigenes IList<T> implementieren und anstelle des Arrays verwenden, dann hast Du die volle Kontrolle, auch über das, was im Indexer passiert.
Oder Du gibst deiner Test-Klasse einen eigenen Indexer, allerdings habe ich bisher noch keine Situation gesehen, wo das sinnvoll und die Klasse keine Auflistung war, was zumindest ein sehr starkes Argument für IList<T> gewesen wäre.

3.003 Beiträge seit 2006
vor 2 Jahren

ILIst ist ein bisschen Kanone auf den Spatzen, der vorgeschlagene Indexer kommt deiner Anforderung am nächsten:


class Test
{
    private string[] _array = new string[] { "Element 1", "Element 2", "Element 3" };
    public string this[int index] 
    {
        get => _array[index];
        set 
        {
            onItemChanged(index);
            _array[index] = value;
        }
    }
    
    private void onItemChanged(int index) => Console.WriteLine(index); // todo
}
class Program
{
    static void Main(string[] args)
    {
        Test test = new Test();
        test[1] = "Ersetze dieses Element";
    }
}

Natürlich vor dem Zugriff auf's Array immer schön prüfen, ob es das Element überhaupt gibt.

Grüße,

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

2.078 Beiträge seit 2012
vor 2 Jahren

Mich stört beim Indexer, wenn er in einer Klasse genutzt wird, die keine Auflistung sein soll.
Ob das hier der Fall ist, können wir natürlich nicht sagen.

Und bezüglich IList und Kanonen und Spatzen:


class MyList<T> : Collection<T>
{
    protected override void ClearItems()
    {
        base.ClearItems();

        OnChanged();
    }
    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);

        OnChanged();
    }
    protected override void RemoveItem(int index)
    {
        base.RemoveItem(index);

        OnChanged();
    }
    protected override void SetItem(int index, T item)
    {
        base.SetItem(index, item);

        OnChanged();
    }

    private void OnChanged()
    {
        // ...
    }
}

Ich finde, das ist ein vertretbarer Aufwand 😁
Allerdings erinnert mich das ein bisschen an die ObservableCollection, vielleicht ist die hier eine bessere Alternative?

J
Jonas007 Themenstarter:in
37 Beiträge seit 2020
vor 2 Jahren

Ich hab mir das mit den Indexern einmal angesehen und das funtkioniert klasse. Auch wenn die Funktion nicht ganz so verwendet wird wie gedacht...
Ich danke euch 😁