Как запретить вызов метода С#

Я хочу разрешить вызов метода только из определенных методов. Взгляните на приведенный ниже код.

  private static void TargetMethod()
  {
  }

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

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

Мне нужно, чтобы AllowedMethod мог вызвать TargetMethod. Как это сделать, используя классы из System.Security.Permissions?

Обновлено: Спасибо за ваши ответы, но я не хочу обсуждать дизайн моего приложения. Я просто хочу знать, можно ли это сделать с помощью .net-безопасности или нет?

Ответы

Ответ 1

CAS не может этого сделать, если код работает полностью.

Если код выполняется в режиме полного доверия (т.е. обычное, локальное приложение, а не приложение Silverlight или что-то запущено из сети), то все проверки .NET CAS полностью обойдены; любой атрибут безопасности просто игнорируется.

CAS просто выполняет стеки для определения разрешений, но вы также можете это сделать, как ранее указал Дарин, просто проверив StackTrace.

Ответ 2

Вы можете решить это, используя обычный объектно-ориентированный дизайн. Переместите AllowedMethod в новый класс и сделайте ForbiddenMethod приватным методом этого класса:

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

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

AllowedMethod имеет доступ к закрытым членам, но никто не имеет.

Ответ 3

Я считаю, что вы должны попытаться структурировать свой код в значащих классах и использовать стандартные модификаторы доступа (private, protected, public, internal). Есть ли какая-то конкретная причина, почему это не решит вашу проблему?

Единственная альтернатива, о которой я могу думать, будет включать в себя перемещение стека вызовов из вызываемого абонента, но это, скорее всего, приведет к беспорядку кода и субоптимальной производительности.

Ответ 4

Вы можете проверить стек вызовов, чтобы выполнить это, но он довольно медленный. Я бы не рекомендовал его, если его можно избежать.

Если вы все еще хотите это сделать, вам нужно быть осторожным, чтобы избежать использования метода inlining, иначе ваш код может внезапно перестать работать в версиях Release.

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

Насколько я знаю, для этого нет готовых атрибутов.

Ответ 5

Я не уверен, что это возможно с помощью System.Security.Permissions, но внутри TargetMethod вы можете получить вызывающего и действовать соответственно:

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

Ответ 7

Используя атрибуты, вы можете решить эту проблему.

Использовать условные атрибуты.

В верхней части

#define "Show" 


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

Будет вызван один из ваших метоз.