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

Я хочу позволить называть метод только из конкретных методов. Смотрите на код ниже.

  private static void TargetMethod()
  {
  }

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

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

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

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

14
задан Moslem Ben Dhaou 23 April 2014 в 07:16
поделиться

7 ответов

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

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

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

4
ответ дан 1 December 2019 в 06:16
поделиться

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

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

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

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

6
ответ дан 1 December 2019 в 06:16
поделиться

Используйте вызов :

call bat1.cmd
call bat2.cmd

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

В основном, если у вас есть такой пакет:

@echo off
echo Foo
batch2.cmd
echo Bar

, то он будет выводиться только

Foo

Если вы пишете его как

@echo off
echo Foo
call batch2.cmd
echo Bar

, однако, он будет выводиться

Foo
Bar

, потому что после завершения batch2 управление программой передается обратно в исходный файл пакета.

-121--1608992-

Я не знаю ни одной библиотеки, но лучший алгоритм может заключаться в том, чтобы получить доступ ко всем возможным числам/языкам/ординалам в карте < целое число, карте < язык, последовательность > > .

private static Map<Integer, Map<Locale, String>> ordinals = new HashMap<Integer, Map<Locale, String>>();
static {
    Map<Locale, String> ordinal1 = new HashMap<Locale, String>();
    ordinal1.put(Locale.ENGLISH, "st");
    ordinal1.put(Locale.FRENCH, "er");
    ordinals.put(1, ordinal1);
    Map<Locale, String> ordinal2 = new HashMap<Locale, String>();
    ordinal2.put(Locale.ENGLISH, "nd");
    ordinals.put(2, ordinal2);
    Map<Locale, String> ordinal3 = new HashMap<Locale, String>();
    ordinal3.put(Locale.ENGLISH, "rd");
    ordinals.put(3, ordinal3);
    Map<Locale, String> ordinal4 = new HashMap<Locale, String>();
    ordinal4.put(Locale.ENGLISH, "th");
    ordinal4.put(Locale.FRENCH, "ème");
    ordinals.put(4, ordinal4);
}

Затем метод getOrdingFor () может в основном выглядеть как (очевидная обработка ошибок во время выполнения в стороне):

public static String getOrdinalFor(int value, Locale locale) {
    return ordinals.get(value).get(locale);
}

Для других чисел, которые не охватываются картой, можно рассмотреть возможность обратного отсчета числа до тех пор, пока на карте не будет найдено совпадение (чтобы запрос порядкового номера для, например, 5 или выше вернул порядковый номер для 4 (первое следующее совпадение при обратном отсчете)):

public static String getOrdinalFor(int value, Locale locale) {
    Map<Locale, String> ordinal = null;
    for (int i = value; i > 0 && (ordinal == null || !ordinal.containsKey(locale)); i--) {
        ordinal = ordinals.get(i);
    }
    return ordinal != null ? ordinal.get(locale) : null; // Or other default? 
}
-121--504478-

С помощью атрибутов можно

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

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

#define "Show" 


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

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

2
ответ дан 1 December 2019 в 06:16
поделиться

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

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

8
ответ дан 1 December 2019 в 06:16
поделиться

Я не уверен, что это достижимо с System.security.Подними , но внутри TargetMethod Вы могли бы получить абонента и действовать соответственно:

StackTrace stackTrace = new StackTrace();
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
4
ответ дан 1 December 2019 в 06:16
поделиться

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

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

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

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

24
ответ дан 1 December 2019 в 06:16
поделиться

Вы можете использовать объекты CodeAccessPermissionPerision. Вам придется реализовать интерфейс в своем собственном объекте, чтобы он работал так, как вы предлагаете, хотя.

http://msdn.microsoft.com/en-us/library/system.security.codeAccessPermission.aspx

3
ответ дан 1 December 2019 в 06:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: