Announcement

Collapse
No announcement yet.

IEnumerable, Array[] Zugriff Inkonsequent?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • IEnumerable, Array[] Zugriff Inkonsequent?

    Hey zusammen

    Ich weiss das ist eigentlich keine wirklich große Sache. Aber ich bin mir nicht ganz schlüssig wie ichs machen soll.

    Ich habe mir für einen Speicherbereich folgende Klasse definiert:

    [highlight=c#]
    public class MemoryBlock:IEnumerable<AddressedByte>
    {
    private readonly int _startAddress;

    private readonly Byte[] _bytes;

    public MemoryBlock(int startAddress, byte[] bytes)
    {
    _startAddress = startAddress;
    _bytes = bytes;
    }

    public byte this[int address]
    {
    get { return _bytes[GetArrayIndex(address)]; }
    set { _bytes[GetArrayIndex(address)] = value; }
    }

    public MemoryBlock GetPart(int startAddress, int length)
    {
    var bytes = from addressedByte in this
    where addressedByte.Address > startAddress - 1 && addressedByte.Address < startAddress + length
    select addressedByte.Value;

    return new MemoryBlock(startAddress,bytes.ToArray());
    }

    private int GetArrayIndex(int address)
    {
    return address - _startAddress;
    }

    #region Implementation of IEnumerable

    public IEnumerator<AddressedByte> GetEnumerator()
    {
    return new MemoryBlockEnumerator(this);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
    return GetEnumerator();
    }

    #endregion
    }
    [/highlight]

    [highlight=c#]
    public class AddressedByte
    {
    public int Address { get; set; }
    public byte Value { get; set; }
    }
    [/highlight]

    Jetzt gibt aber der Array Zugriff über this [int address] etwas anderes zurück als der Enumerator. Allerdings stelle ichs mir für die Benützung praktischer vor. Ist das Inkonsequent?

  • #2
    Hallo Florian,

    in der Methode GetPart(int startAddress, int length); kannst du besser mit Skip und Take arbeiten.

    In der Methode IEnumerable.GetEnumerator(); würde ich zur Sicherheit explizt angeben welche GetEnumerator-Methode zurückgegeben werden soll - nicht dass versehentlich mal (zB Refactoring) eine Endlosrekursion entsteht. Hier also explizit
    [highlight=c#]
    public IEnumerator<AddressedByte> GetEnumerator()
    {
    return new MemoryBlockEnumerator(this);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
    return (this as IEnumerable<AddressedByte).GetEnumerator();
    }
    [/highlight]

    Jetzt gibt aber der Array Zugriff über this [int address] etwas anderes zurück als der Enumerator. Allerdings stelle ichs mir für die Benützung praktischer vor. Ist das Inkonsequent?
    Da versteh ich nicht ganz worauf du hinaus willst. Mit this[...] erfolgt indizierter Zugriff und es wird ein byte zurückgegeben und mit dem Enumerator wird "drüberiteriert", also eine Menge von bytes zurückgegeben. Das sind 2 verschiedene Dinge und insofern sehe ich da keine Inkonsistenz.


    mfG Gü
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

    Comment


    • #3
      Skip und Take hatte ich mir auch schon angeschaut, aber fangen die nicht immer am Anfang an nehmen dann solange bis das erste nicht mehr passt? Ich möchte ja aus der Mitte des Arrays Elemente holen. Wie würdest Du das mit Skip und Take formulieren?

      Der Tip mit dem Enumerator ist gut. Das werd ich auf jeden Fall reinbauen.

      Die Inkonsequenz besteht darin, dass mein Enumerator AddressedByte Objekte zurückgibt und der Indexer direkt ein byte. Theoretisch könnte der Indexer ja auch AddressedByte Objekte zurückliefern und wäre dann konsistent mit dem Enumerator.

      Edit:

      Ach lach ich glaub mir ist grad die Lösung für Skip und Take eingefallen Irgendwie total vergessen, dass man das danach ja nochmal aufrufen kann.

      [highlight=c#]
      var bytes = _bytes.Skip(startAddress - _startAddress).Take(length);
      [/highlight]
      Zuletzt editiert von fanderlf; 03.09.2010, 14:33.

      Comment


      • #4
        Hallo Florian,

        Die Inkonsequenz besteht darin, dass mein Enumerator AddressedByte Objekte zurückgibt und der Indexer direkt ein byte.
        Jetzt hab ich verstanden was du meinst. Da es aber weder dich noch micht stört - und ich es erst jetzt verstanden habe - würde ich sagen dass das kein Problem darstellt. Ich hab auch schön öfters solche Klassen gesehen - ich denke auch im Framework.

        Lösung für Skip und Take eingefallen
        Fluent Interfaces sind cool


        mfG Gü
        "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

        Comment


        • #5
          Originally posted by gfoidl View Post
          Fluent Interfaces sind cool
          Joa da kann ich Dir nur zustimmen. Ich finde meine Klasse auch toll, weil das auch eine mit einem mehr oder weniger Fluent Interface wird

          Ausserdem find ich auch Extension Methods derzeit sehr schick, da man diese auch auf Interfaces definieren kann. Heisst ich implementiere ein Interface und hab auf dem Interface definierte Extensions direkt dabei. Natürlich ginge das auch mit einer abstrakten Basisklasse. Aber da muss ich schon wieder wissen welche Basisklasse ich brauche

          Comment


          • #6
            Hallo,

            da wir gerade dabei sind etwas vom Thema abzudriften
            Kennst du Code Contracts? Diese können auch auf Interfaces angewandt werden. Finde ich sehr praktsich.


            mfG Gü
            "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

            Comment


            • #7
              Ich hatte da vor einiger Zeit mal was drüber gelesen. Also so Design By Contract. Wird ja auch in den DDD Büchern immer angepriesen. Ich weiss auch dass es sowas seit 4.0 gibt, aber leider hatte ich noch nicht die Muße mich da reinzufriemeln. Es gäbe ja soooo viele Sachen -.-
              NHibernate 3.0 ist jetzt auch rausgekommen. ASP.NET MVC 2 würde mich auch interessieren (hab schon ein Buch zuhause liegen ). WPF bin ich grad momentan dran. Ein kleines Projekt hab ich auch noch. Nächste Usergroup halte ich noch einen Vortrag zu OpenXML. Also eine kleine Einführung. So viel zu tun und so wenig Zeit

              Comment


              • #8
                Hallo,

                da du jetzt genug Stress hast bist du somit aufgestiegen in die Riege der richtigen Programmierer

                Offtopic-Mode wieder aus.


                mfG Gü
                "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                Comment


                • #9
                  Na super jetzt hab ich mir 2 Extension Methoden für mein Byte Array gebraucht und festgestellt dass diese vollkommen überflüssig sind -.-
                  Für meine Compare Funktion gibts SequenceEqual und für die GetPart(int startIndex, int length) gibts Take und Skip. Dann werd ich die wohl gleich wieder rauswerfen.

                  Edit: Meine GetPart Methode lass ich so. Überal Take und Skip zu verwenden wird mir etwas zu unübersichtlich. Da ich das doch recht oft brauchen werde
                  Zuletzt editiert von fanderlf; 03.09.2010, 16:20.

                  Comment

                  Working...
                  X