【问题标题】:Is there a way to restrict access to a public method to only a specific class in C#?有没有办法限制对公共方法的访问仅限于 C# 中的特定类?
【发布时间】:2011-02-07 11:15:11
【问题描述】:

我在 C# 中有一个带有公共方法的 A 类。我想只允许 B 类访问此方法。这可能吗?

更新

这就是我想做的:

public class Category
{
    public int NumberOfInactiveProducts {get;}
    public IList<Product> Products {get;set;}

    public void ProcessInactiveProduct()
    {
        // do things...

        NumberOfInactiveProducts++;
    }
}

public class Product
{
    public bool Inactive {get;}
    public Category Category {get;set;}

    public void SetInactive()
    {
        this.Inactive= true;
        Category.ProcessInactiveProduct();
    }
}

我希望其他程序员这样做:

var prod = Repository.Get<Product>(id);
prod.SetInactive();

我想确保他们不会手动调用 ProcessInactiveProduct:

var prod = Repository.Get<Product>(id);
prod.SetInactive();
prod.Category.ProcessInactiveProduct();

我想只允许 Category.ProcessInactiveProduct 访问类 Product。其他类不应调用 Category.ProcessInactiveProduct。

【问题讨论】:

  • +1 非常有趣的问题。
  • 如果您只想让 B 类访问它 - 那么这不是“公共”方法。

标签: c# oop


【解决方案1】:

将两个类放在一个单独的程序集中,并将方法设为内部。

【讨论】:

  • +1 哈哈!不错的答案!我可能有点过度思考我的答案:)
  • (已删除评论...我将其作为单独的程序集阅读,如复数形式)
【解决方案2】:

如果你将 A 类设为 B 内的私有嵌套类,则可以:

class B
{
    class A
    {
        public Int32 Foo { get; set; }
    }
}

只有B 才能看到A 及其在此示例中的成员。

或者,您可以将B 嵌套在A 中:

class A
{
    Int32 Foo { get; set; }

    public class B { }
}

在这种情况下,每个人都可以看到AB,但只有B 可以看到A.Foo

【讨论】:

  • 谢谢,但它们是独立的(不是嵌套的)类。我想从 A 类中隐藏一个方法,但只向 1 个特定的类(B 类)显示(允许它)。 A 和 B 没有嵌套。
  • 如果不嵌套类型,您将无法使用默认语言结构来执行此操作。您可能必须考虑基于安全的方法(仅在类型“身份验证”时才允许访问),但我相信您对此的需求可能会暴露您的设计中的缺陷。更大的图景是什么?也许如果您编辑帖子并提供更多详细信息,我可以帮助您找到解决方案:)
【解决方案3】:

您可以通过这种方式限制方法/类的访问:

[StrongNameIdentityPermissionAttribute(SecurityAction.Demand, PublicKey="…hex…", Name="App1", Version="0.0.0.0")]
public class Class1 { } 

查看此处http://msdn.microsoft.com/en-us/library/c09d4x9t.aspx 了解更多信息。

托管代码提供了多种方法来限制方法访问
...

  • 将方法访问权限限制为指定身份的调用者 - 本质上是您选择的任何特定证据(强名称、发布者、区域等)。

【讨论】:

    【解决方案4】:

    您的问题没有现成的答案。

    如果它们已经在同一个程序集中,为什么不将方法设置为内部作用域呢?

    如果它们在不同的程序集中,您可以使用涵盖所有内部方法的“friend”语法。

    您最好的解决方案可能是将公共方法的访问权限限制为特定程序集。这意味着某人不能只编写一个新程序集并继续调用您的公共方法。鉴于您似乎有一个域模型,看起来您应该允许从其他域对象调用此方法,但可能不允许从业务逻辑调用。这可以通过为域模型 DLL 分配一个唯一的强名称来实现。

    您可以限制对公共方法的访问,只允许它被程序集中满足给定公钥的方法调用。见msdnStrongNameIdentityPermission

    【讨论】:

      【解决方案5】:

      您可以使用观察者类型的模式,其中类别注册对产品上特定事件的兴趣(可能是 ProductInactivated 事件?),然后适当地处理逻辑。这种基于事件的模式非常常见,并且大大减少了耦合。 Category 最终对其自身的状态负责,并且不依赖 Product 了解包含它的内容来保持 Category 的状态完好无损。产品只是在发生事情时告诉感兴趣的客户。

      另一种选择是重构您的 Category 类,使其包含或包含在某个 CategoryProductServices 对象中,该对象封装了 Product 需要对其包含的 Category 执行的方法。在创建类别和产品的上下文中,将此 CategoryProductServices 对象的实例传递给产品而不是完整的类别。这种设计使接口保持公开,但阻止您的客户端访问服务,因为它们无法检索实例。它还放松了 Products 与 Category 类的紧密耦合,将其仅限于 Products 必须注意的那些服务。这让产品负责状态,但至少限制了它需要知道/做的事情。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-30
        • 2017-03-10
        • 2021-01-23
        • 1970-01-01
        • 1970-01-01
        • 2020-01-07
        • 1970-01-01
        相关资源
        最近更新 更多