2010-01-15 24 views
14

Quiero permitir llamar al método solo desde los métodos particulares. Eche un vistazo al código a continuación.Cómo prohibir llamar a un método C#

private static void TargetMethod() 
    { 
    } 

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

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

Necesito solamente AllowedMethod podría llamar a TargetMethod. ¿Cómo hacerlo usando clases de System.Security.Permissions?

Actualizado: Gracias por sus respuestas, pero no quiero debatir sobre el diseño de mi aplicación. Solo quiero saber si es posible hacerlo usando la seguridad de .net o no.

+5

Si es privado, ¿por qué es importante? –

+15

¿Cómo se vota esta pregunta 9 veces en solo 6 minutos? – shoosh

+3

¿Estás tratando de protegerte de ti mismo? Aparte de eso, no puedo imaginar el uso para esto. – Skurmedel

Respuesta

4

CAS no puede hacer esto si el código se ejecuta con plena confianza.

Si el código se está ejecutando en plena confianza (es decir, una aplicación local normal, no una aplicación Silverlight o algo que se ejecuta desde la red), entonces todo.Las comprobaciones NET CAS están completamente anuladas; cualquier atributo de seguridad simplemente se ignora.

CAS simplemente camina la pila para determinar los permisos, sin embargo, y usted puede hacer eso también, como Darin señaló anteriormente simplemente marcando el StackTrace.

8

Creo que usted debe tratar de estructurar su código en clases meaningfull, y el uso de los modificadores de acceso estándar (private, protected, public, internal). ¿Hay alguna razón específica por la cual esto no resolvería su problema?

La única alternativa que puedo pensar involucraría atravesar la pila de llamadas desde dentro del destinatario, pero eso probablemente produciría desorden de código y un rendimiento subóptimo.

4

no estoy seguro si esto se puede lograr con System.Security.Permissions, pero dentro TargetMethod que podría tener la persona que llama y actuar en consecuencia:

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

+1; y parece ser posible encapsular eso implementando 'CodeAccessPermission' –

+0

, sí, lo sé. Pero estoy interesado en cómo hacerlo con los atributos de seguridad. – alga

+0

Esta técnica es lenta y potencialmente frágil: el método de inicialización por parte de JITter podría causar que la llamada 'GetMethod' devuelva resultados inesperados. (Por supuesto, puede decirle al JETter que no se alinee, como en la respuesta de Thorarin). – LukeH

24

puede resolver este utilizando el diseño orientado a objetos normales. AllowedMethod mover a una nueva clase y hacer ForbiddenMethod un método privado de esa clase:

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

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

AllowedMethod tiene acceso a los miembros privados, pero nadie más tiene.

6

Puede examinar la pila de llamadas para lograr esto, pero es bastante lento. No lo recomendaría si se puede evitar.

Si todavía desea hacer esto, debe tener cuidado de evitar el método de alineación también, o su código puede dejar de funcionar repentinamente en versiones de lanzamiento.

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

Que yo sepa, no hay atributos listos para usar para hacer esto.

2

Al usar Atributos puede resolver este problema.

Usar atributos condicionales.

En la parte superior

#define "Show" 


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

Uno de sus methos se llamará.

+2

Bueno, eso elimina 'HiddenMethod' por completo. Creo que lo que quiere la alga es elegir unos pocos métodos selectos que pueden llamar a 'TargetMethod' y denegar * todos los demás *, incluidos los que están en código de terceros, para llamar a' TargetMethod'. La compilación condicional no ayudará a lograr esto ^^ –

Cuestiones relacionadas