2010-01-15 13 views
14

Voglio consentire di chiamare il metodo solo dai metodi particolari. Dai un'occhiata al codice qui sotto.Come proibire di chiamare un metodo C#

private static void TargetMethod() 
    { 
    } 

    private static void ForbiddenMethod() 
    { 
    TargetMethod(); 
    } 

    private static void AllowedMethod() 
    { 
    TargetMethod(); 
    } 

Mi serve solo AllowedMethod può chiamare TargetMethod. Come farlo utilizzando le classi da System.Security.Permissions?

Aggiornamento: Grazie per le vostre risposte, ma non voglio discutere sul design della mia applicazione. Voglio solo sapere se è possibile farlo usando la sicurezza .net o no?

+5

Se è privato, perché è importante? –

+15

In che modo questa domanda è stata votata 9 volte in soli 6 minuti? – shoosh

+3

Stai cercando di proteggerti da te stesso? Oltre a questo non riesco a immaginare l'uso per questo. – Skurmedel

risposta

4

CAS non può farlo se il codice è in esecuzione in piena fiducia.

Se il codice è in esecuzione in Full Trust (vale a dire un'applicazione normale, locale, non un'applicazione Silverlight o qualcosa eseguito dalla rete), quindi tutto.I controlli NET CAS sono completamente bypassati; qualsiasi attributo di sicurezza viene semplicemente ignorato.

CAS sposta semplicemente lo stack per determinare le autorizzazioni, tuttavia, e lo puoi fare anche tu, come ha fatto notare Darin in precedenza controllando semplicemente lo StackTrace.

8

Credo che si dovrebbe cercare di strutturare il codice in classi meaningfull, e utilizzare i modificatori di accesso standard (private, protected, public, internal). C'è qualche ragione specifica per cui questo non risolverà il tuo problema?

L'unica alternativa a cui riesco a pensare, implicherebbe l'attraversamento dello stack di chiamate dall'interno del destinatario, ma ciò probabilmente produrrebbe problemi di codice e prestazioni subottimali.

4

io non sono sicuro se questo è ottenibile con System.Security.Permissions, ma dentro TargetMethod si potrebbe ottenere il chiamante e agire di conseguenza:

StackTrace stackTrace = new StackTrace(); 
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name); 
+0

+1; e sembra essere possibile incapsulare quello implementando 'CodeAccessPermission' –

+0

sì, lo so. Ma sono interessante come farlo con gli attributi di sicurezza. – alga

+0

Questa tecnica è lenta e potenzialmente fragile: l'inlining del metodo da parte di JITter può causare la chiamata 'GetMethod' per restituire risultati imprevisti. (Si può, ovviamente, dire al JITter di non in linea, come nella risposta di Thorarin.) – LukeH

24

si può risolvere questo progettazione orientata agli oggetti normali utilizzando. Spostare AllowedMethod ad una nuova classe e fare ForbiddenMethod un metodo privato di quella classe:

public class MyClass 
{ 
    public void AllowedMethod() { // ... } 

    private void TargetMethod() { // ... } 
} 

AllowedMethod ha accesso ai membri privati, ma nessun altro ha.

6

È possibile esaminare lo stack di chiamate per ottenere ciò, ma è piuttosto lento. Non lo consiglierei se può essere evitato.

Se si desidera comunque eseguire questa operazione, è necessario fare attenzione a evitare l'inlining del metodo oppure il codice potrebbe smettere improvvisamente di funzionare in build di rilascio.

[MethodImpl(MethodImplOptions.NoInlining)] 
private static void TargetMethod() 
{ 
    StackFrame fr = new StackFrame(1, false); 
    Console.WriteLine(fr.GetMethod().Name); 
} 

Per quanto ne so, non esistono attributi predefiniti per farlo.

2

Utilizzando gli attributi è possibile risolvere questo problema.

Usa attributi condizionali.

Nella top

#define "Show" 


    public void TargetMethod() 
    { 
     //Code 
    } 
    [ Conditional("Hidden")] 
    public void HiddenMethod() 
    { 
     TargetMethod() 
    } 
[ Conditional("Show")] 
    public void AllowMethod() 
    { 
     TargetMethod() 
    } 

Uno dei vostri methos sarà chiamato.

+2

Bene che rimuove del tutto "HiddenMethod". Penso che ciò che l'alga vuole, è scegliere alcuni metodi che sono autorizzati a chiamare 'TargetMethod' mentre negano * tutti gli altri *, compresi quelli in codice di terze parti, per chiamare' TargetMethod'. La compilazione condizionale non aiuterà a raggiungere questo ^^ –

Problemi correlati