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

Vas*_*sya 9 .net c# naming-conventions

我正在开发一个符合CLS的类型库,我在它里面有一个类,它包含私有,受保护和公共字段和属性.我使用下划线符号(_)作为私有或受保护字段的前缀,并使用少许第一个字母来区分具有相同名称的属性.它看起来如此:

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

public int Age { get { return this._get; } }
}
Run Code Online (Sandbox Code Playgroud)

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

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; } }
}
Run Code Online (Sandbox Code Playgroud)

然后我试着这样做:

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; } }
}
Run Code Online (Sandbox Code Playgroud)

请告诉我,这些案例的开发人员之间符合CLS的符号或惯例是什么?我是否像C-style一样使用l_age前缀?

Mar*_*ell 10

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

private int _age;
public int Age {
    get { return this._age ; }
    protected set { this._age = value; }
}
Run Code Online (Sandbox Code Playgroud)

或者干脆:

public int Age { get; protected set; }
Run Code Online (Sandbox Code Playgroud)

如果你正确地封装它,那么调用该字段并不重要,因为该类型之外的任何东西都不能看到它.


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

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

在这里,我再次断言这个领域没有理由得到保护; 该事件不属于派生类.它有2个可以执行的合理操作:

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

前者应该通过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);
}
Run Code Online (Sandbox Code Playgroud)

而且......就是这样!

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

不需要任何非私人领域.