2012-02-08 15 views
16

Czy można to zrobić w C# 3 lub 4? Może z odrobiną refleksji?Uruchomić metodę przed wszystkimi metodami klasy

class Magic 
{ 

    [RunBeforeAll] 
    public void BaseMethod() 
    { 
    } 

    //runs BaseMethod before being executed 
    public void Method1() 
    { 
    } 

    //runs BaseMethod before being executed 
    public void Method2() 
    { 
    } 
} 

EDIT

Jest alternatywnym rozwiązaniem dla tego dokonać Magic Singleton i umieścić kod na getter instancji statycznego. Tak zrobiłem:

public class Magic 
{ 

    private static Magic magic = new Magic(); 
    public static Magic Instance 
    { 
     get 
     { 
      magic.BaseMethod(); 
      return magic; 
     } 
    } 

    public void BaseMethod() 
    { 
    } 

    //runs BaseMethod before being executed 
    public void Method1() 
    { 
    } 

    //runs BaseMethod before being executed 
    public void Method2() 
    { 
    } 
} 
+4

Co powiesz na konstruktora? – JConstantine

+1

Używanie konstruktora nie jest rozwiązaniem, ponieważ gdybym miał wykonać, powiedzmy, dwie metody jednej instancji, wystarczyłoby tylko raz wykonać metodę basemethod. Również bardzo mało istotne dla instancji statycznych. –

+0

Można to zrobić za pomocą 'dynamic' i implementując [' IDynamicMetaObjectProvider'] (http://msdn.microsoft.com/en-us/library/system.dynamic.idynamicmetaobjectprovider.aspx). Umożliwi to uruchomienie własnego kodu podczas wiązania, co ma miejsce przed wykonaniem metody. Uwaga: ta sugestia jest dostarczana jako ciekawostka. To naprawdę nie jest dobry sposób na rozwiązanie problemu. – Brian

Odpowiedz

7

Jest alternatywnym rozwiązaniem dla tego , spraw, aby Magic był singletonem i umieść swój kod na pobierającym statyczną instancję. To jest to co zrobiłem.

public class Magic{ 

private static Magic magic; 
public static Magic Instance{ 
    get 
    { 
    BaseMethod(); 
    return magic; 
    } 
} 

public void BaseMethod(){ 
} 

//runs BaseMethod before being executed 
public void Method1(){ 
} 

//runs BaseMethod before being executed 
public void Method2(){ 
} 
} 
+0

to wygląda interesująco, ale nie zadziała. prywatne pole nie jest inicjowane. Jeśli wyjaśnisz, w jaki sposób zainicjować magiczne pole, może to zadziałać. – hakan

+0

Możesz zrobić leniwy init, tzn. Sprawdzić, czy null przed uzyskaniem dostępu (zwykle tylko pierwszy raz). Jeśli tak, zainicjuj to. – CBinet

8

Nie możesz tego zrobić automatycznie w języku C# - prawdopodobnie powinieneś patrzeć na AOP, np. z PostSharp.

+0

Mam pewne wątpliwości dotyczące AOP jako rozwiązanie dla tego, ponieważ uważam, że OP chce wykonać metodę przed jednym wywołaniem metody, a później nie "już" aspektu. Może jakaś flaga klasy instancji takiej jak _Initialized_ i czy jest _true_, nic nie robi w tym aspekcie? –

+0

@ MatíasFidemraizer: Nie wierzę w to, na podstawie późniejszego komentarza: "Używanie konstruktora nie jest rozwiązaniem, ponieważ gdybym miał wykonać, powiedzmy, dwie metody jednej instancji, dostałbym tylko metodę base do uruchomienia raz "- wierzę więc, że OP chce, aby metoda była uruchamiana w * każdym * wywołaniu. –

+0

Cóż, PostSharp (lub jakikolwiek inny framework AOP) to nasze rozwiązanie!Ten komentarz został opublikowany po moich wątpliwościach. I uważam, że jest to właściwa odpowiedź, ponieważ _IL tkactwo_ jest lepsze niż pośredniczenie w tym przypadku. –

0

Właśnie zrobić coś jasne, dlaczego po wdrożenie nie zadziała:

public class Magic{ 

private static Magic magic = new Magic(); 
public static Magic Instance{ 
    get 
    { 
    magic.BaseMethod(); 
    return magic; 
    } 
} 

public void BaseMethod(){ 
} 

//runs BaseMethod before being executed 
public void Method1(){ 
} 

//runs BaseMethod before being executed 
public void Method2(){ 
} 
} 

w przypadku, gdy po prostu chcesz posiadać Magic obiekt, metoda zostanie przypadkowo nazywa się:

Magic m = Magic.Instance; //this will trigger unwanted call on BaseMethod 

a także jeśli ktoś będzie chciał wywołać BaseMethod, zostanie ona wywołana dwukrotnie:

Magic.Instance.BaseMethod(); //two calls of the BaseMethod 

które oczywiście mają obejście, aby powrócić niepożądanych obiektów przy użyciu otrzymujemy:

var unused = Magic.Instance; 

Tylko Podsumowując: Nie jest to możliwe (przynajmniej jeszcze) w C#.

Powiązane problemy