in einer Generic Class new Operator verwenden?



  • volkard schrieb:

    Prof84 einfach ignorieren!

    Ein echter volkard:
    - 0 konstruktiven Beitrag
    - 0 Bedeutung
    - 0 Selbstbewusstsein

    vom Hersteller garantiert 😃



  • Jungs... 😃

    Fechtet ihr hier einen pers. Disput in meinem Thread aus oder wie muss ich das verstehen? Zeigt eure Fachstärke und helft mir lieber 😉



  • Bei dem new-constraint kann man wirklich nur den parameterlosen Kosntruktor verwenden.
    Du könntest aber alternativ eine Schnittstelle deklarieren und diese dann für deine Resource-Klassen verwenden, z.B.

    interface IResource
    {
      public string Filename { get; set; }
    }
    

    Und diese dann als weitere Beschränkung (constraint) angeben:

    class RessourceHolder<RessourceT>
            where RessourceT : IResource, new() // new() muß immer am Ende stehen
    

    Und die Benutzung wäre dann statt über den Konstruktor:

    var resource = new RessourceT();
    resource.Filename = filename;
    mRessourceMap.Add(resource);
    

    Alternativ auch eine Methode Load(string resource) o.ä. in der Schnittstelle.

    PS: Wenn du viele verschiedene Ressourcetypen hast, dann könntest du auch eine Basisklasse (z.B. ResourceBase) benutzen, in der du dann schon die Schnittstelle definierst (anstatt immer wieder neu in der Ressource-Klasse zu erzeugen).
    PPS: Im Englischen schreibt sich Ressource nur mit einem s: Resource 😉



  • Danke für die Hilfe - klingt nach einer Lösung - werde mal ein wenig drauf rumkauen bis ich es letztendlich gerallt habe 😉

    Bei großen Fragen komme ich nochmal auf euch zurück - bis dahin...Licht aus, Hirn an 😉



  • Gut ich glaube nicht das dies eine Lösung wäre.
    Immerhin muss ich irgendwie dafür sorgen das die ResourceT Objekte in die ResourceMap gelangen also in die List. Da der Aufruf später über diese Liste erfolgen soll.

    Siehe Methode Get()
    (welche noch nicht geschrieben ist)

    Außerdem geht das leider mit dem Interface den Resource Klassen anfügen nicht. Ich nutze SFML.NET API und dort sind die Klassen halt festgelegt - möchte die Dinger ungern abändern.



  • Hier auch ein Versuch von mir zu deiner Idee:

    ResourceT resource = new ResourceT();
    resource.filename = "./path/pic.png";
    mResourceMap.Add(resource);
    

    Das Prinzip welches du meinst habe ich verstanden. Ich umgehe den Konstruktor in dem Falle hier. Leider gibt es keine public Property für filename in der Klasse. Daher keine Chance auf diesen Weg.

    Laut Galileo Buch:

    Der generische Typparameter kann nunmehr nur durch Objekte konkretisiert werden, die einen öffentlichen, parameterlosen Konstruktor unterstützen. Einen parametrisierten Konstruktor vorzuschreiben ist nicht möglich. Werden mehrere Bedingungen definiert, steht new() grundsätzlich immer am Ende der Aufzählung.

    Hier wird also nicht einmal auf ein späteres Kapitel verwiesen wo die Sache vielleicht doch gelöst worden wäre. Irgendwie schwer zu glauben das es in der großen Lösungswelt von C# keine Möglichkeit gibt. Sehnt man sich hier nach der Macht von C++ zurück?



  • Dann bleibt wohl wirklich nur

    var resource = (ResourceT)Activator.CreateInstance(typeof(ResourceT), new object[] { filename });
    

    (sieht vllt. etwas unelegant aus, entspricht aber quasi "new ResourceT(filename)")



  • Activator.CreateInstance() ist also hier die "moderne" Lösung?

    Sollte mir mal ne Doku über die Activator Klasse reinziehen - danke auf jedenfall für die Tipps Leute !



  • var resource = (ResourceT)Activator.CreateInstance(typeof(ResourceT), new object[] {filename});
                    mResourceMap.Add(resource);
    

    UND ES WERDE LICHT.

    Ich finde die Lösung garnicht mal so unelegant ehrlich gesagt. Habe einiges dazu gelernt nun - ebenfalls die Nutzung von var, an die ich mich mal langsam gewöhnen sollte.

    Vielen Danke an alle für die Hilfe !



  • Mir ist nicht ganz klar was die Klasse eigentlich machen soll.
    Also was ihr "Mehrwert" gegenüber Dictionary<string, ResourceT> ist.



  • Es ist eine Generic Klasse welche Resourcen in sich halten soll also heavyweights.

    In der Game.cs wirkt das sich dann so aus:

    ResourceHolder<Texture> mTextureHolder;
    ResourceHolder<SoundBuffer> mSoundHolder;
    [...]
    mTextureHolder = new ResourceHolder<Texture>();
    mSoundHolder = new ResourceHolder<SoundBuffer>();
    [...]
    //Load Textures
    mTextureHolder.Load("./Media/Textures/Eagle.png");
    
    //Load Sounds
    mSound = new Sound();
    mSoundHolder.Load("./Media/Sounds/wing.wav");
    
    //init mPlayer object
    mPlayer = new Sprite(mTextureHolder.Get());
    mPlayer.Position = new Vector2f(100.0f, 100.0f);
    
    //init mSound object
    mSound.SoundBuffer = mSoundHolder.Get();
    


  • OK.
    Jetzt verstehe ich es noch weniger.

    Wieso nicht einfach

    Texture mTexture;
    SoundBuffer mSound;
    [...]
    mTexture = null;
    mSoundBuffer = null;
    [...]
    //Load Textures
    mTexture = new Texture("./Media/Textures/Eagle.png");
    
    //Load Sounds
    mSoundBuffer = new Sound("./Media/Sounds/wing.wav");
    
    //init mPlayer object
    mPlayer = new Sprite(mTexture);
    mPlayer.Position = new Vector2f(100.0f, 100.0f);
    
    //init mSound object
    mSound.SoundBuffer = mSoundBuffer.Get();
    

    ?

    ps.

    heavyweights

    Eine Reosource-Holder Klasse für Schwergewichte ohne IDisposable?



  • hustbaer schrieb:

    OK.
    Jetzt verstehe ich es noch weniger.

    Wieso nicht einfach

    Texture mTexture;
    SoundBuffer mSound;
    [...]
    mTexture = null;
    mSoundBuffer = null;
    [...]
    //Load Textures
    mTexture = new Texture("./Media/Textures/Eagle.png");
     
    //Load Sounds
    mSoundBuffer = new Sound("./Media/Sounds/wing.wav");
     
    //init mPlayer object
    mPlayer = new Sprite(mTexture);
    mPlayer.Position = new Vector2f(100.0f, 100.0f);
     
    //init mSound object
    mSound.SoundBuffer = mSoundBuffer.Get();
    

    ?

    ps.

    heavyweights

    Eine Reosource-Holder Klasse für Schwergewichte ohne IDisposable?

    Naa Hustbaer du darfst mich nicht überschätzen ich bin ein Anfänger und im Bezug mit IDiposable noch keinen Kontakt - ich folge nur einem Handbuch zum Game Design mit SFML API. Und dort wird eine ResourceHolder Template Klasse als Beispiel genannt.

    Ich verstehe deinen Einwurf das eine Generic Klasse für das kurze Spektrum überflüssig ist. Vielleicht ist es nur eine Beispiel Angelegenheit vom Lernbuch.

    Die ResourceHolder Klasse hält ja eine Liste aller ResourceT Instanzen (somit bei TextureHolder eine Sammlung an Texturen bei SoundHolder eine Sammlung an SoundBuffer Objekten aka Sounds. Die kann ich dann für die lightweights Sound oder Sprite abrufen und das Ganze mit der Get() Methode (welche natürlich noch nen Auswahlparameter erhält). Ich finde das vom Design her garnicht soooo übel.

    Und dein Code oben überzeugt mich nicht Chef ! 🤡 Wenn dann richtig - ein bisschen lesen kann ich ja doch schon 💡



  • Was, weil ich in Zeile 1 mSound statt mSoundBuffer geschrieben habe?
    OMG ja wie furchtbar.

    Falke88 schrieb:

    und das Ganze mit der Get() Methode (welche natürlich noch nen Auswahlparameter erhält). Ich finde das vom Design her garnicht soooo übel.

    Du zeigst Code einer Klasse her die für nix gut ist und stellst dazu Fragen.
    Wenn dann einer nachfragt wozu du die Klasse eigentlich überhaupt hast kommt "na da kommt ja noch X als Funktionalität dazu". Als ob wir das riechen könnten.

    BTW: Ich sehe immer noch keinen Grund hier etwas anderes als Dictionary<string, ResourceT> zu verwenden.
    Und auch keinen Grund warum die ResourceHolder Klasse auch für das Erzeugen der Resourcen zuständig sein soll.
    Also wieso nicht einfach eine Add Funktion statt einer Load Funktion?
    (Und vielleicht merkst du jetzt warum ich immer wieder auf Dictionary<string, ResourceT> zurückkomme...)


Anmelden zum Antworten