2012-02-08 10 views
16

È possibile farlo in C# 3 o 4? Forse con qualche riflessione?Eseguire un metodo prima di tutti i metodi di una classe

class Magic 
{ 

    [RunBeforeAll] 
    public void BaseMethod() 
    { 
    } 

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

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

EDIT

Esiste una soluzione alternativa per questo, fare Magic un singoletto e inserire il codice sul getter dell'istanza statica. Questo è quello che ho fatto:

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

Che ne dici di un costruttore? – JConstantine

+1

L'utilizzo di un costruttore non è una soluzione, perché se dovessi eseguire, diciamo, due metodi di un'istanza, otterrei il basemethod da eseguire solo una volta. Anche molto inadeguato per istanze statiche. –

+0

Si potrebbe fare ciò usando 'dynamic' e implementando [' IDynamicMetaObjectProvider'] (http://msdn.microsoft.com/en-us/library/system.dynamic.idynamicmetaobjectprovider.aspx). Ciò ti consentirà di eseguire il tuo codice durante l'associazione, che avviene prima dell'esecuzione di un metodo. Nota: questo suggerimento è fornito come una curiosità. In realtà non è un buon modo per risolvere il tuo problema. – Brian

risposta

7

Esiste una soluzione alternativa per questo , rendi Magic un singleton e metti il ​​tuo codice sul getter dell'istanza statica. Questo è quello che ho fatto.

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

questo sembra interessante ma non funzionerà. campo privato non è avviato. Se spieghi come avviare il campo magico, questo potrebbe funzionare. – hakan

+0

Si potrebbe eseguire un init pigro, controllando se null prima dell'accesso (solitamente solo la prima volta). Se lo è, lo instanziate. – CBinet

8

Non è possibile eseguire questa operazione automaticamente in C# - probabilmente dovresti esaminare AOP, ad es. con PostSharp.

+0

Ho qualche dubbio su AOP come soluzione per questo, perché credo che OP voglia eseguire un metodo prima di una chiamata al metodo e più tardi non "usi" più l'aspetto. Forse qualche flag di istanza di classe come _Initialized_ e if _true_, non fa nulla nell'aspetto? –

+0

@ MatíasFidemraizer: Non credo, in base a un commento successivo: "L'utilizzo di un costruttore non è una soluzione, perché se dovessi eseguire, ad esempio, due metodi di un'istanza, otterrei il basemethod da eseguire una sola volta "- Quindi credo che l'OP voglia che il metodo sia eseguito su * ogni * invocazione. –

+0

Bene, quindi, PostSharp (o qualsiasi altro framework AOP) è la nostra soluzione!Questo commento è stato pubblicato dopo i miei dubbi. E, credo che questa sia la risposta giusta, perché _IL weaving_ è meglio che proxying per questo caso. –

0

solo per fare una cosa chiara perché la seguente implementazione non funziona:

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(){ 
} 
} 

nel caso si desidera solo per tenere un oggetto Magic, il metodo sarà chiamato a caso:

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

e anche se uno si vuole chiamare il BaseMethod, esso sarà chiamato due volte:

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

che ovviamente hanno una soluzione, per tornare oggetti indesiderati utilizzando get:

var unused = Magic.Instance; 

Solo per riassumere: Questo non è possibile (almeno ancora) in C#.

Problemi correlati