von List<> ableiten und wieder nach List<> casten



  • Hallo,
    ich benötige eine Änderung in der List<T>-Klasse (Filter), will diese aber in meinen vorhandenen ablösen, ohne die Skripte zu ändern.

    Dazu habe ich die Klasse erstellt, und die Deklaration + Initialisierung der Instanz abgeändert.
    Nun habe ich aber Probleme beim casten in die (Basi) List<T> - Klasse.

    Beispiel:

    public class FilteredList<T> : List<T>
    {
    	// [....]
    }
    public void Foo(List<string> Bar)
    {
    }
    FilteredList<string> MyList = new FilteredList<string>();
    Foo(MyList); // Fehler
    Foo((List<string>)MyList); // Fehler
    

    Ist das casten überhaupt irgendwie möglich (mit dem Typparamater) ?
    Oder muss ich doch den kompletten Code umschreiben, dass nun explizit die FilteredList -Klasse erwartet wird?



  • Zeig ein vollständiges Minimalbeispiel, das das Problem reproduziert. Meins zeigt nämlich keinen "Fehler".



  • ohnee, habe den Fehler gefunden.

    Der entscheidende Code:

    class Program
    	{
    
    		static void Main(string[] args)
    		{
    			FilteredList<string> MyList = new FilteredList<string>();
    			MyList = Test(MyList);
    		}
    		public static List<string> Test(List<string> MyList)
    		{
    			return(MyList);
    		}
    	}
    
    	public class FilteredList<T> : List<T>
    	{
    	}
    

    Das casten wieder zurück von List<> nach FilteredList<> schlägt fehl (obwohl es ja ein FilteredList-Objekt ist.

    Gibt es trotzdem eine Möglichkeit wieder von List<> nach FilteredList zu casten? Es ist ja wirklich ein FilteredList-Objekt



  • Tachyon76 schrieb:

    Gibt es trotzdem eine Möglichkeit wieder von List<> nach FilteredList zu casten?

    Äh, ja?



  • MFK schrieb:

    Tachyon76 schrieb:

    Gibt es trotzdem eine Möglichkeit wieder von List<> nach FilteredList zu casten?

    Äh, ja?

    So kommt man also auf soviele Beiträge.
    Kompliment zu einem so herausragendem Beitrag 🙂

    Und wie castet man wieder "zurück" von der Basisklasse zur vererbten Klasse?

    Edit: Casting mittels "as" bringt mit nicht viel, da ich dann auch jeden Aufruf im Code umschreiben muss. Wäre dann einfacher mittels suchen+ersetzen den Typ (von List => FilteredList) zu ändern



  • Tachyon76 schrieb:

    So kommt man also auf soviele Beiträge.

    Genau, durch endloses Nachfragen, weil manche Leute einfach nicht in der Lage sind, ihr Problem ordentlich zu beschreiben.

    Tachyon76 schrieb:

    Kompliment zu einem so herausragendem Beitrag 🙂

    Wer Ja/Nein-Fragen stellt, muss mit Ja/Nein-Antworten rechnen.

    Tachyon76 schrieb:

    Edit: Casting mittels "as" bringt mit nicht viel, da ich dann auch jeden Aufruf im Code umschreiben muss. Wäre dann einfacher mittels suchen+ersetzen den Typ (von List => FilteredList) zu ändern

    Dann ändere den Rückgabetyp von Test und schreib den Cast in die Funktion.



  • Tachyon76 schrieb:

    MFK schrieb:

    Tachyon76 schrieb:

    Gibt es trotzdem eine Möglichkeit wieder von List<> nach FilteredList zu casten?

    Äh, ja?

    So kommt man also auf soviele Beiträge.
    Kompliment zu einem so herausragendem Beitrag 🙂

    Und wie castet man wieder "zurück" von der Basisklasse zur vererbten Klasse?

    Edit: Casting mittels "as" bringt mit nicht viel, da ich dann auch jeden Aufruf im Code umschreiben muss. Wäre dann einfacher mittels suchen+ersetzen den Typ (von List => FilteredList) zu ändern

    Angesichts Deiner Intention, vielleicht hilft hier Dir dieses Code-Beispiel:

    public struct PolygonPointers
        {
            public int docStartOffset { set; get; }
            public int selectEndOffset { set; get; }
        }
    
        public class OT_data
        {
    ...
            public List<PolygonPointers> SelectMarks { set; get; }
    ...
        }
    ...    // EDIT: um Filteranweisung ergänzt
                var todelPolygons =     from x in ot_data.SelectMarks
                                        where x.docStartOffset >= docStartOffset
                                                && x.docStartOffset + x.selectEndOffset
                                                < markEndOffset
                                        select x;
    ...
                        // nutze HashSet
                    var setToRemove = new HashSet<PolygonPointers>(todelPolygons);
                    ot_data.SelectMarks.RemoveAll(x => setToRemove.Contains(x));
    

    Mit der HashSet übergibst Du die Pointer für die Listen.
    Vor allem die Lösung ist schnell, vermeidet Redundanz, abdeckungssicher und kurz.
    So brauchst Du Dich mit dem Vererbungsproblem nicht rumquälen.

    btw. Schau Dir mal das Schlüsselwort base an.



  • Mal abgesehen davon,

    was macht deine FiltereList eig. genau? Welche erweiterung is da drin?

    vll. mal andere design überlegen, und sich das casgten sparen!


Log in to reply