什么是符合CLS的受保护字段的命名约定?

时间:2011-09-27 10:12:57

标签: c# .net naming-conventions

我正在开发一个符合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的符号或惯例是什么?我是否可以使用C风格的前缀,如l_age?

2 个答案:

答案 0 :(得分:10)

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

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

或简单地说:

public int Age { get; protected set; }

如果你正确封装它,那么无关紧要该字段被调用的内容,因为该类型之外的可以看到它。


在评论中,然后提出事件问题,例如:

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. 订阅/取消订阅该活动
  3. 前者应该通过On*模式完成;后者应该只使用常规访问器(否则它会违反锁定)。此外,即使我们认为lock(this.StateChanged)是一个拼写错误(这将是一个非常非常糟糕的事情,因为锁定对象 - 不会起作用所有 ),请注意,在C#4.0中,当您编写“类似字段”时,编译器内置了一个更高效的锁定策略(使用Interlocked而不是Monitor) “事件(即没有明确的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);
    }
    

    并且......就是这样!

    • 如果子类想要订阅/取消订阅(不理想,但是meh)它只使用StateChanged +=StateChanged -=
    • 如果子类想要调用该事件,则调用OnStateChanged(...)
    • 如果子类想要调整事件逻辑,则会将override添加到OnStateChanged

    不需要任何非私人字段。

答案 1 :(得分:2)

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

  

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

这可能就是为什么你找不到任何关于命名它们的有用指导的原因(事实上,naming guidelines只是指向Field Design页面。)