【问题标题】:What is a right CLS-compliant naming convention for protected fields?什么是受保护字段的正确 CLS 兼容命名约定?
【发布时间】:2011-09-27 10:12:57
【问题描述】:

我正在开发一个符合 CLS 的类型库,其中有一个类,其中包含私有、受保护和公共字段和属性。我使用下划线符号 (_) 作为私有或受保护字段的前缀,并使用小首字母将它们与具有相同名称的属性区分开来。看起来是这样的:

class SomeClass
{
private int _age; //Here is OK

public int Age { get { return this._get; } }
}

但是当我尝试使用受保护的字段时,我遇到了下一个问题:

class SomeClass
{
protected int _age; //Here is NOT CLS-compliant (because of _ can't be the first symbol of identifier)

public int Age { get { return this._get; } }
}

然后我尝试这样做:

class SomeClass
{
protected int age; //Here is NOT CLS-compliant (because of age and Age differ only in one symbol)

public int Age { get { return this._get; } }
}

请告诉我,在这种情况下,开发人员之间的正确 CLS 兼容表示法或约定是什么?我可以使用 l_age 等 C 风格的前缀吗?

【问题讨论】:

    标签: c# .net naming-conventions


    【解决方案1】:

    这是一个更正确的版本,IMO:

    private int _age;
    public int Age {
        get { return this._age ; }
        protected set { this._age = value; }
    }
    

    或者简单地说:

    public int Age { get; protected set; }
    

    如果你正确地封装它,那么该字段被称为什么并不重要,因为在该类型之外没有任何东西可以看到它。


    在cmets中,接着就提出了事件的问题,举个例子:

    protected EventHandler<StateChangedEventArgs> _stateChanged;
    public event EventHandler<StateChangedEventArgs> StateChanged
    {
        add { lock (this.StateChanged) { this._stateChanged += value; } }
        remove { lock (this.StateChanged) { this._stateChanged -= value; } }
    }
    

    在此我再次断言,没有理由让该字段受到保护;事件不属于派生类。它有 2 个可以执行的合理操作:

    1. 调用事件
    2. 订阅/取消订阅活动

    前者应该通过On* 模式完成;后者应该只使用常规访问器(否则它会违反锁)。另外,即使我们假设lock(this.StateChanged) 是一个错字(这将是一个非常非常糟糕的事情作为锁定对象 - 它根本不起作用),请注意,在 C# 4.0 中,当您编写“类字段”事件(即没有显式add/remove)。因此,这里的首选方法是:

    public event EventHandler<StateChangedEventArgs> StateChanged;
    protected virtual void OnStateChanged(StateChangedEventArgs args) {
        var snapshot = StateChanged; // avoid thread-race condition
        if(snapshot != null) shapshot(this, args);
    }
    

    然后……就是这样!

    • 如果子类想要订阅/取消订阅(不是很理想,但是嗯),它只使用StateChanged +=StateChanged -=
    • 如果子类要调用事件,它调用OnStateChanged(...)
    • 如果子类想要调整事件逻辑,它会在OnStateChanged 中添加一个override

    不需要任何非私有字段。

    【讨论】:

    • 嗯...如何处理事件?
    • @Praetor12 关于事件是什么?派生类需要访问该字段的什么?也许添加一个特定的事件相关示例?
    • 是的。基类有一个事件,由派生类方法调用。对于这种机制,我这样做了:protected EventHandler _stateChanged;公共事件 EventHandler StateChanged; { 添加 { 锁定 (this.StateChanged) { this._stateChanged += 值; } } 移除 { 锁定 (this.StateChanged) { this._stateChanged -= value; } } }
    • @Praetor12 如果您的 lock 实际上与 pastie.org/2599084 相同,请注意 that too not 实际上是一个正常运行的 lock策略,即使编译器没有给出警告。它不符合lock 的预期目的。
    • @TimDams - 那是因为不存在“官方”约定 - 我在我的回答中指出了为什么 - 微软一直建议不应该存在这样的野兽。
    【解决方案2】:

    为了支持 Marc 的回答,微软在 Field Design 上的指导指出:

    公共和受保护字段的版本不好,并且不受代码访问安全要求的保护。不要使用公开可见的字段,而是使用私有字段并通过属性公开它们。

    这可能就是为什么您在命名它们时找不到任何有用的指导(事实上,naming guidelines 只是指向字段设计页面)。

    【讨论】:

      猜你喜欢
      • 2020-01-31
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      • 1970-01-01
      • 2018-01-18
      • 1970-01-01
      • 1970-01-01
      • 2010-09-20
      相关资源
      最近更新 更多