Как запретить вызов метода С#
Я хочу разрешить вызов метода только из определенных методов. Взгляните на приведенный ниже код.
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);
Ответ 6
Возможно, вы сможете использовать объекты CodeAccessPermission. Вы должны реализовать интерфейс в своем собственном объекте, чтобы он работал, как вы предлагаете.
http://msdn.microsoft.com/en-us/library/system.security.codeaccesspermission.aspx
Ответ 7
Используя атрибуты, вы можете решить эту проблему.
Использовать условные атрибуты.
В верхней части
#define "Show"
public void TargetMethod()
{
//Code
}
[ Conditional("Hidden")]
public void HiddenMethod()
{
TargetMethod()
}
[ Conditional("Show")]
public void AllowMethod()
{
TargetMethod()
}
Будет вызван один из ваших метоз.