【问题标题】:Different access to property for different classes不同类对属性的不同访问
【发布时间】:2012-01-24 11:53:13
【问题描述】:

我有一个基础(抽象)类Component。我想控制对派生类属性的访问,这样每个人都可以获得读取权限,但只有某些类才允许写入权限。

那些“某些类”目前是实现抽象基类MessageHandler<TMessage> 的任何东西。理想情况下,我还希望实现IMessageHandler 的类能够访问,但我认为这会使要求更加严格。

这将在 xbox 上运行,因此我想避免创建临时对象(例如只读副本)。我还想尽量减少获取读取/写入值的方法调用次数。

Component 类和MessageHandler<TMessage> 类目前在它们自己的程序集中,其他项目在使用我的 API 时都会引用它们。

我猜我将不得不以某种方式改变我的模型,但我无法理解它。

public abstract class Component
{

}

public class DerivedComponentA : Component
{
    int property {get; set;}
}

public abstract class MessageHandler<TMessage>
{

}

public class IntMsghandler : MessageHandler<int>
{
    void DoThing(DerivedComponentA derivedComponentA)
    {
        derivedComponentA.property = 5; // Allowed
    }
}

public class AnyClass // Doesn't inherit MessageHandler, or implement IMessageHandler
{
    void DoThing(DerivedComponentA derivedComponentA)
    {
        derivedComponentA.property = 5; // Not Allowed
    }
}

【问题讨论】:

  • 如果有任何不清楚的地方,请告诉我,我会修改。
  • 不清楚你想限制什么访问。您要限制访问的属性在哪里?
  • @Matten:这是非法的。您不能更改被覆盖成员的访问修饰符。
  • 看起来你想要的实际上并不是继承。

标签: c# access-modifiers


【解决方案1】:

隔离(基于您提出的问题和我的理解)是基于基类定义(如果有的话)。这意味着隔离应该从它开始。

或者,如果你说,如果某些class X 实现MessageHandler 应该能够以多种方式作用于class Y 类型的对象。那,imo,意味着两者之间存在艰难的关系 class Y 和 MessageHandler。

这让我觉得你可以这样做:

  • 仅在DerivedComponentA 的属性上公开get
  • 在MessageHandler 中定义一个通用的protected SetProperty(Component compo, string propertyName, object propertyValue) 并使用反射设置所需的属性。

以这种方式,在 any Component 派生类上设置属性的唯一可能方法是使用 MessageHandler 方法,因此仅适用于从它派生的那些。对于其余可用类型,您提供 only public get (readonly) 属性来读取数据。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我建议您在这里使用接口。有一个只读接口IReadOnlyComponent,它有一个只读属性和一个IWritableComponent : IReadOnlyComponent,它为该属性添加了一个Set 方法。
    抽象基类Component 实现了IWritableComponent,因此具有只读属性和Set 方法。
    仅将组件实例作为IWritableComponent 传递给从MessageHandler 继承的类或实现IMessageHandler 并将其作为IReadOnlyComponent 传递给所有其他类。

    【讨论】:

      【解决方案3】:

      你能不能像这样控制setter:

      public string Prop {
        get { return ...; }
        set { if (!(this is MessageHandler<TMessage>)) 
                 throw Exception(...);
              .... setter code;
        }
      }
      

      【讨论】:

      • 对不起,我可能不太清楚,该属性在组件类上,而不是消息处理程序上(尽管消息处理程序是要更改值的那个)。添加了代码。
      • 另外,理想情况下我希望它在编译时强制执行(虽然不知道这有多现实)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-03
      相关资源
      最近更新 更多