Я хочу позволить называть метод только из конкретных методов. Смотрите на код ниже.
private static void TargetMethod()
{
}
private static void ForbiddenMethod()
{
TargetMethod();
}
private static void AllowedMethod()
{
TargetMethod();
}
Мне нужен только AllowedMethod, мог назвать TargetMethod. Как сделать это с помощью классов от System.Security.Permissions
?
Обновленный: Спасибо за Ваши ответы, но я не хочу дебатировать о дизайне моего приложения. Я просто хочу знать, что действительно ли возможно сделать это использование безопасность .NET или нет?
CAS не может сделать это, если код работает в полном доверии.
Если код выполняется в полном доверие (то есть нормальное, локальное приложение, не приложение Silverlight или что-то работает из сети), то все проверки .NET CAS полностью обойдены; Любой атрибут безопасности просто игнорируется.
CAS просто проводит стек, чтобы определить разрешения, хотя, и вы можете сделать это тоже, так как Дарин указывал ранее, просто проверяя Stacktrace
.
Вы можете проверить стек вызовов, чтобы выполнить это, но это довольно медленно. Я бы не рекомендовал этого, если этого можно избежать.
Если вы все еще хотите сделать это, вам нужно быть осторожным, чтобы избежать встраивания методов, иначе ваш код может внезапно перестать работать в сборках Release.
[MethodImpl(MethodImplOptions.NoInlining)]
private static void TargetMethod()
{
StackFrame fr = new StackFrame(1, false);
Console.WriteLine(fr.GetMethod().Name);
}
Насколько мне известно, для этого нет готовых атрибутов.
Используйте вызов
:
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
управление программой передается обратно в исходный файл пакета.
Я не знаю ни одной библиотеки, но лучший алгоритм может заключаться в том, чтобы получить доступ ко всем возможным числам/языкам/ординалам в карте < целое число, карте < язык, последовательность > >
.
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()
}
Будет вызван один из ваших методов.
Я полагаю, что вы должны попытаться структурировать свой код в значимых классах, и использовать стандартные модификаторы доступа (,
, ,
,
, Внутренний
). Есть ли какая-либо конкретная причина, по которой это не решит вашу проблему?
Единственная альтернатива, которую я могу подумать, будет включать в себя пересечение стека вызовов из калле, но, скорее всего, даст беспорядок кода и неоптимальные характеристики.
Я не уверен, что это достижимо с System.security.Подними
, но внутри TargetMethod
Вы могли бы получить абонента и действовать соответственно:
StackTrace stackTrace = new StackTrace();
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
Это можно решить, используя обычное объектно-ориентированное проектирование. Переместите AllowedMethod
в новый класс и сделайте ForbiddenMethod
закрытым методом этого класса:
public class MyClass
{
public void AllowedMethod() { // ... }
private void TargetMethod() { // ... }
}
AllowedMethod имеет доступ к закрытым членам, но больше ни у кого нет.
Вы можете использовать объекты CodeAccessPermissionPerision. Вам придется реализовать интерфейс в своем собственном объекте, чтобы он работал так, как вы предлагаете, хотя.
http://msdn.microsoft.com/en-us/library/system.security.codeAccessPermission.aspx