是否可以自定义访问修饰符行为?

时间:2011-11-16 15:19:59

标签: c# .net access-modifiers

我有一个由两个程序集组成的winform应用程序:业务层和前端层。每个用户控件(前端层)与业务层的类相关,即 CustomerUserControl 使用 Customer 类。

可编辑属性(即 Customer.Name )具有公共设置器,以便可以通过前端控件修改其值。

我的问题是:是否可以更改属性的setter可访问性,使其仅对特定类具有或多或少的限制性。在我的示例中, Customer.Name setter将是内部的,前端控件无法访问它,但可以访问其相应的控件 CustomerUserControl 。否则,setter将是公共的,但 CustomerUserControl 以外的控件无法访问。

是否可以实现此类自定义访问权限?

3 个答案:

答案 0 :(得分:3)

我会使用内部修饰符作为setter。这使得它只能在组件内访问。如果CustomerUserControl在另一个程序集中,那么您可以使用InternalsVisibleToAttribute

[assembly: InternalsVisibleTo("assembly name")] 

编辑:你是对的。这是另一种可能性: 声明一个接口,该接口将由允许设置名称的控件实现:

public interface ICustomerNameProvider
{
    string CustomerName { get; }
}

在客户中添加方法:

public void SetName(ICustomerNameProvider customerNameProvider)
{
    this.Name = customerNameProvider.CustomerName;
}

CustomerUserControl会像这样调用它:

cust.SetName(this);

原因这不是绝对万无一失的,但是不小心通过错误的控制将变得不可能。

答案 1 :(得分:1)

据我所知,没有办法将你要求的内容直接应用于属性设置器,因为它不知道调用的起源。但是,您可以使用mutator方法拼凑一些东西:

public class Customer
{
   ...
   public string Name
   {
      get;
      private set;
   }

   public void SetName(string callingControlName, string newName)
   {
      // you'd use TypeOf the same way to pass in callingControlName
      if(TypeOf(this).Name + "UserControl" == callingControlName)
         this.Name = newName;
   }
   ...
}

请注意,这是非常紧密耦合和糟糕的设计实践,但它应该做你想要的,只要你严格遵守问题中列出的命名约定(Customer匹配1:1 {{1 }})。顺便说一下,我不是只是静态地将CustomerUserControlcallingControlName进行比较,以便在可维护性方面略有改进,以防您想要重命名CustomerUserControl类。另外需要注意的是,通过调用"CustomerUserControl"可以轻松解决这个问题。希望你不要把这个暴露给会那样做的人,但这完全有可能。

这里的真正问题是您的业务层不应该依赖于您的表示层。为什么需要限制对特定UserControl的设置访问?如果您真正需要(我想不出一个)只能从某个UI类访问业务属性Customer.SetName("CustomerUserControl","badName"),那么就需要重新设计一些应用程序。

答案 2 :(得分:-1)

您可以限制get或set访问器的范围,如下所示:

//private set accessor - this is what you're looking for
public int SomeProperty { get; private set; } 

//private get accessor
public int SomeOtherProperty { private get; set; }