2011-09-27 29 views
9

Tôi đang phát triển thư viện kiểu tuân thủ CLS và tôi có một lớp bên trong Thư viện, chứa các trường và thuộc tính riêng tư, được bảo vệ và công khai. Tôi sử dụng ký hiệu gạch dưới (_) làm tiền tố cho các trường riêng tư hoặc được bảo vệ và chữ cái đầu tiên để phân biệt chúng với các thuộc tính có cùng tên. Nó trông giống như vậy:Quy ước đặt tên tuân thủ CLS phù hợp cho các trường được bảo vệ là gì?

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

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

Nhưng khi tôi cố gắng sử dụng các lĩnh vực bảo vệ tôi va chạm với một vấn đề tiếp theo:

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; } } 
} 

Sau đó, tôi cố gắng làm theo cách như vậy:

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; } } 
} 

Hãy , cho tôi biết, ký hiệu hoặc quy ước phù hợp với CLS giữa các nhà phát triển cho những trường hợp như thế nào? Tôi có sử dụng tiền tố theo kiểu C như l_age không?

Trả lời

10

Dưới đây là một phiên bản chính xác hơn, IMO:

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

hoặc đơn giản là:

public int Age { get; protected set; } 

Nếu bạn đúng cách đóng gói nó, sau đó nó không quan trọng gì lĩnh vực này được gọi là, như không có gì bên ngoài loại đó có thể nhìn thấy.


Trong ý kiến, câu hỏi về sự kiện sau đó được nâng lên, với ví dụ:

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

Ở đây tôi một lần nữa khẳng định rằng có không có lý do cho lĩnh vực này được bảo vệ; sự kiện không thuộc về đối với lớp dẫn xuất. Nó có 2 hoạt động hợp lý nó có thể muốn thực hiện:

  1. gọi sự kiện
  2. đăng ký/hủy đăng ký sự kiện

Cựu nên được thực hiện thông qua các mô hình On*; sau này chỉ nên sử dụng các accessors thông thường (nếu không nó vi phạm khóa). Ngoài ra, ngay cả khi chúng tôi giả định rằng lock(this.StateChanged) là một lỗi đánh máy (đó sẽ là một điều thực sự, thực sự xấu để sử dụng như là các đối tượng khóa -Nó sẽ không làm việc ở tất cả), lưu ý rằng trong C# 4.0 trình biên dịch có một chiến lược khóa hiệu quả hơn nhiều sẵn có (sử dụng Interlocked thay vì Monitor) khi bạn viết một sự kiện "giống như trường" (tức là không rõ ràng add/remove). Do đó, cách tiếp cận ưa thích ở đây sẽ là:

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

và ... đó là nó!

  • nếu lớp con muốn đăng ký/hủy đăng ký (không lý tưởng, nhưng MEH) nó chỉ sử dụng StateChanged +=StateChanged -=
  • nếu lớp con muốn gọi sự kiện này, nó gọi OnStateChanged(...)
  • nếu lớp con muốn tinh chỉnh logic sự kiện, nó thêm override vào

không cần cho bất kỳ trường không riêng tư nào.

+0

Mmm ... Làm gì với sự kiện? – Vasya

+0

@ Praetor12 những gì * về * sự kiện? những gì hiện các lớp học có nguồn gốc cần truy cập vào các lĩnh vực cho có? Có lẽ thêm một ví dụ cụ thể liên quan đến sự kiện? –

+0

Vâng. Lớp cơ sở có một sự kiện, được gọi bằng các phương thức lớp dẫn xuất. Đối với cơ chế như vậy tôi đã làm như vậy: bảo vệ EventHandler _stateChanged; sự kiện công khai EventHandler StateChanged; { thêm {lock (this.StateChanged) {this._stateChanged + = value; }} xóa {lock (this.StateChanged) {this._stateChanged - = value; }} } – Vasya

2

Để sao lưu câu trả lời của Marc, các hướng dẫn về Field Design từ Microsoft khẳng định: lĩnh vực

công cộng và bảo vệ không phiên bản tốt và không được bảo vệ bởi nhu cầu bảo mật truy cập mã. Thay vì sử dụng các trường hiển thị công khai, hãy sử dụng các trường riêng tư và hiển thị chúng thông qua các thuộc tính.

Đây có lẽ là lý do tại sao bạn sẽ không tìm thấy bất kỳ hướng dẫn hữu ích nào về cách đặt tên cho chúng (trên thực tế, naming guidelines chỉ cần quay lại trang Thiết kế trường).

Các vấn đề liên quan