如何禁止调用方法C#
Posted
技术标签:
【中文标题】如何禁止调用方法C#【英文标题】:How to forbid calling a method C# 【发布时间】:2011-01-05 11:50:32 【问题描述】:我希望只允许从特定方法调用该方法。看看下面的代码。
private static void TargetMethod()
private static void ForbiddenMethod()
TargetMethod();
private static void AllowedMethod()
TargetMethod();
我只需要 AllowedMethod 可以调用 TargetMethod。如何使用来自System.Security.Permissions
的类来做到这一点?
更新:感谢您的回答,但我不想争论我的应用程序的设计。我只是想知道是否可以使用 .net 安全性来做到这一点?
【问题讨论】:
如果它是私有的,为什么重要? 这个问题是如何在短短 6 分钟内获得 9 次投票的? 你想保护你自己吗?除此之外,我无法想象它的用途。 @alga:这样做非常慢,所以如果我是你,我会重新考虑这个特殊的习惯。至少对于经常调用的方法。 “我不想争论应用程序的设计”——你来错地方了。 【参考方案1】:您可以使用普通的面向对象设计来解决这个问题。将AllowedMethod
移动到一个新类,并使ForbiddenMethod
成为该类的私有方法:
public class MyClass
public void AllowedMethod() // ...
private void TargetMethod() // ...
AllowedMethod 可以访问私有成员,但其他人没有。
【讨论】:
【参考方案2】:我认为您应该尝试在有意义的类中构建您的代码,并使用标准的访问修饰符(private
、protected
、public
、internal
)。有什么具体原因不能解决您的问题吗?
我能想到的唯一替代方法是从被调用者内部遍历调用堆栈,但这可能会产生代码混乱和次优性能。
【讨论】:
【参考方案3】:您可以检查调用堆栈来完成此操作,但速度相当慢。如果可以避免,我不会推荐它。
如果您仍想这样做,您还需要小心避免方法内联,否则您的代码可能会在发布版本下突然停止工作。
[MethodImpl(MethodImplOptions.NoInlining)]
private static void TargetMethod()
StackFrame fr = new StackFrame(1, false);
Console.WriteLine(fr.GetMethod().Name);
据我所知,没有现成的属性可以做到这一点。
【讨论】:
【参考方案4】:如果代码以完全信任的方式运行,CAS 就无法做到这一点。
如果代码在完全信任下执行(即正常的本地应用程序,而不是 Silverlight 应用程序或从网络运行的东西),则所有 .NET CAS 检查都将被完全绕过;任何安全属性都会被忽略。
CAS 只是简单地遍历堆栈以确定权限,您也可以这样做,正如 Darin 之前指出的,只需检查 StackTrace
。
【讨论】:
【参考方案5】:我不确定这是否可以通过 System.Security.Permissions
实现,但在 TargetMethod
内部,您可以获取调用者并采取相应措施:
StackTrace stackTrace = new StackTrace();
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
【讨论】:
+1;并且似乎可以通过实现CodeAccessPermission
来封装它
是的,我知道。但我很感兴趣如何使用安全属性来做到这一点。
这种技术很慢并且可能很脆弱:JITter 的方法内联可能会导致GetMethod
调用返回意外结果。 (当然,您可以告诉 JITter 不要内联,就像 Thorarin 的回答一样。)【参考方案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()
将调用您的一个方法。
【讨论】:
好吧,这完全删除了HiddenMethod
。我认为 alga 想要的是选择一些允许调用 TargetMethod
的方法,同时拒绝 所有其他(包括 3rd 方代码中的方法)调用 TargetMethod
。条件编译无助于实现这一目标^^以上是关于如何禁止调用方法C#的主要内容,如果未能解决你的问题,请参考以下文章