Funktion per Name Aufruf in Static Class

DrMueller

Erfahrenes Mitglied
Hallo Leute,

wieder mal ein spezielles Problem: Ich mache ein Spiel, wobei ich eine Static Class LevelCreator habe, welche die Felder erstellt.
Nun heissen die Unterfunktionen da alle gleich: InitiateLevel1, InitiateLevel2 etc.
Könnte ich natürlich unschön per Select Case machen, allerdings gibt es wohl auch sowas wie CallByName in VB, siehe hier:
http://stackoverflow.com/questions/4019233/call-by-name-in-c

Dies scheint allerdings nur zu funktionieren, wenn ich eine instanzierte Klasse habe.
Gibt es denn da evtl. eine Möglichkeit, dies in einer Static Class zu machen?

Wie immer vielen Dank im Voraus.


Müller Matthias
 

Cromon

Erfahrenes Mitglied
Hallo DrMueller

Zuerst zu deinem Problem:
Wie im Posting von Stackoverflow angedeutet kannst du dieses mit Reflection lösen.
C#:
Type levelType = typeof(LevelCreator);
int levelNumber = 2;
string methodName = "InitiateLevel" + levelNumber;

MethodInfo method = levelType.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public);
method.Invoke(null, null);

Zu MethodInfo.Invoke:
Der erste Parameter wäre die Instanz der Klasse, da die Methode aber statisch sein soll kommt da null hin. Der zweite Parameter wäre ein Array von Objekten als Parameter. Ich ging mal davon aus dass du keine Parameter hast, daher da auch null. Wäre das nicht so gibst du da einfach ein Array mit deinen Parametern an.

Nun aber noch designtechnisches Wort dazu:
Diese Variante die du da gewählt hast ist sicher nicht die beste. Sie ist relativ langsam und wirkt auch irgendwie unsauber. Schon eine bessere Lösung wäre folgendes:
C#:
class LevelCreator
{
    private static List<Func<LevelObject>> mLevelInitializers = new List<Func<LevelObject>>();

    static LevelCreator()
    {
        mLevelInitializers.Add(loadLevel1);
        mLevelInitializers.Add(loadLevel2);
    }

    private LevelObject loadLevel(string levelName) { return null; }

    public LevelObject loadLevel(int level)
    {
        return mLevelInitializers[level]();
    }

    public LevelObject loadLevel1() { return loadLevel("level1"); }
    public Levelobject loadLevel2() { return loadLevel("level2"); }
};

Viele Grüsse
Cromon
 

DrMueller

Erfahrenes Mitglied
Super vielen Dank für die Antwort.
Ich versuche das mal so nachzubauen.

Vlt. noch gleich eine andere Frage:

Ich gebe einem Formular sowohl Breite als auch Höhe, trotzdem gibt es da Unterschiede. Ich habe bei ClientRectangle festgestellt, dass die Breite tatsächlich einen anderen Wert als die Höhe hat, obwohl ich bei beiden den gleichen Wert mitgebe.
ClientRectangle ist ja readOnly, gibt es da eine Möglichkeit das ClientRectangle direkt zu beeinflussen?


Noch einmal vielen Dank und einen schönen Sonntag.

Müller Matthias
 

Cromon

Erfahrenes Mitglied
Hallo Matthias Müller

Der Grund warum du eine andere Höhe als Breite bekommst ist weil die Grössen die du als Höhe und Breite angibst sich auf das ganze Fenster inklusive Rand beziehen. Da es nur oben eine Titelleiste gibt ist in der Regel das ClientRectangle breiter als hoch da bei der Höhe mehr abgezogen wird.

Du kannst den Form.ClientSize property verwenden, dieser ist auch readwrite.

Grüsse und ebenfalls einen schönen Sonntag,
Cromon
 

Neue Beiträge