Objekt aus Liste mit Delegate löschen ohne neue Klasse zu schreiben?



  • Hallo,

    ich hatte unter VC++ schon mal das PRoblem, dass ich in einer Liste mehrere Objekte einer Klasse gespeichert hatte. Dann bin ich mit foreach durch die Liste gewandert und hab beim Matching ein Predicate benutzt, um das Objekt aus der Liste zu löschen. Dazu musste ich aber einen eigene Klasse schreiben.

    theta hatte mir damals ein Beeispiel gepostet, mit dem es funktioniert hat:

    using namespace System;
    using namespace System::Collections::Generic;
    
    public ref class Person
    {
    public:
        Person(String^ name) : _name(name)
        {
        }
    
    public:
        property String^ Name
        {
            String^ get()
            {
                return _name;
            }
        }
    
    private:
        String^ _name;
    };
    
    public ref class PersonFind
    {
    public:
        PersonFind(String^ name) : _name(name)
        {
        }
    
    public:
        bool Match(Person^ person)
        {
            if (nullptr == person || nullptr == _name)
            {
                return false;
            }
            else
            {
                return person->Name == _name;
            }
        }
    
    private:
        String^ _name;
    };
    
    int main(array<System::String ^> ^args)
    {
        List<Person^>^ list = gcnew List<Person^>();
        list->Add(gcnew Person(L"Jack"));
        list->Add(gcnew Person(L"John"));
        list->Add(gcnew Person(L"Marc"));
        list->Add(gcnew Person(L"Jack"));
        list->Add(gcnew Person(L"Jack"));
        list->Add(gcnew Person(L"Jack"));
    
        Predicate<Person^>^ predicate = gcnew Predicate<Person^>(gcnew PersonFind(L"Jack"), &PersonFind::Match);
        list->RemoveAll(predicate);
    
        return 0;
    }
    

    Meine Frage nun, ob ich das unter C# auch so machen muss, oder ob es da eine elegantere Methode gibt?

    Beste Grüße

    Solick



  • Generell müßtest du auch in C# die RemoveAll-Methode benutzen, welche ein Prädikat verlangt.
    Durch die anonymen Methoden ab C# 2.0 (bzw. Lambda-Ausdrücke ab C# 3.0) läßt es sich jedoch verkürzen:

    list.RemoveAll(delegate(string s) { return s == "Jack"; });
    // bzw.
    list.RemoveAll(s => s == "Jack");
    

    zu letzterem s. http://msdn.microsoft.com/de-de/library/bb397687.aspx



  • Hallo Th69,

    also brauche ich dazu keine eigenen Klasse mehr schreiben, sondern kann zb. in einer Foreach-Schleife alle Elemente einer Liste durchlaufen und mit

    list.RemoveAll(delegate(string s) { return s == "irgendweineBedingung"; });
    

    dann in der Schleife direkt löschen?



  • Nein, denn RemoveAll löscht für dich bereits alle vorkommen die dem Predicate entsprechen, d.h. du brauchst keine Schleife mehr.



  • zudem kann man eine liste die man mit foreach durch laeuft nicht entsprechend bearbeiten - dann muesste man auf eine for ausweichen
    aber die bessere loesung wurde ja schon genannt


Anmelden zum Antworten