【问题标题】:How to forbid calling a method C#如何禁止调用方法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:这样做非常慢,所以如果我是你,我会重新考虑这个特殊的习惯。至少对于经常调用的方法。
  • “我不想争论应用程序的设计”——你来错地方了。

标签: c# .net permissions .net-security


【解决方案1】:

您可以使用普通的面向对象设计来解决这个问题。将AllowedMethod 移动到一个新类,并使ForbiddenMethod 成为该类的私有方法:

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

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

AllowedMethod 可以访问私有成员,但其他人没有。

【讨论】:

    【解决方案2】:

    我认为您应该尝试在有意义的类中构建您的代码,并使用标准的访问修饰符(privateprotectedpublicinternal)。有什么具体原因不能解决您的问题吗?

    我能想到的唯一替代方法是从被调用者内部遍历调用堆栈,但这可能会产生代码混乱和次优性能。

    【讨论】:

      【解决方案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。条件编译无助于实现这一目标^^
            猜你喜欢
            • 2015-08-12
            • 2019-05-12
            • 1970-01-01
            • 2023-03-27
            • 1970-01-01
            • 1970-01-01
            • 2022-11-26
            • 2017-04-28
            • 2016-09-06
            相关资源
            最近更新 更多