phương thức công khai so với nội bộ trên một lớp nội bộ


82
internal class Foo
{
  public void Fee()
  {
    Debug.WriteLine("Fee");
  }

  internal void Fi()
  {
    Debug.WriteLine("Fi");
  }
}

Tôi nghĩ rằng Fee () và Fi () đều có thể truy cập như nhau vì toàn bộ lớp đã là nội bộ. Tôi có đang nhìn ra cái gì đó không? Có lý do gì để chọn công khai hoặc nội bộ cho các phương pháp trong trường hợp như thế này không?


2
@EricLippert đã viết blog ý kiến ​​của mình hôm nay. ericlippert.com/2014/09/15/internal-or-public/#more-2353
ScottS

Câu trả lời:


97

Các internal class Footuyên bố sẽ ghi đè lên khả năng tiếp cận của public void Fee()phương pháp, có hiệu quả làm cho nó nội bộ.

Trong trường hợp này, sử dụng nội bộ so với công khai trên các phương pháp sẽ có tác dụng tương tự. Lý do duy nhất tôi chọn phương thức công khai so với phương thức nội bộ trong trường hợp như thế này là để dễ dàng chuyển đổi sang lớp công khai trong phiên bản tương lai, nếu bạn chọn làm như vậy.


36

Điều duy nhất còn thiếu ở đây trong câu trả lời là tại sao bạn lại làm điều này?

Một số thư viện có nhiều lớp không dành cho người sử dụng thư viện chạm vào mà chúng phải kế thừa các giao diện được đánh dấu là công khai. Ví dụ: tôi có một thư viện với một lớp kế thừa giao diện IComparer nhưng nó chỉ được sử dụng trong nội bộ và tôi không muốn làm lộn xộn khía cạnh công khai của thư viện của mình. Nếu tôi đánh dấu chức năng So sánh được triển khai là bên trong, trình biên dịch sẽ phàn nàn rằng tôi không tích hợp IComparer giao diện.

Vậy làm cách nào để triển khai thành công giao diện và đồng thời ngăn nó không thể truy cập được ở khía cạnh công cộng trong thư viện của tôi? Đánh dấu lớp là nội bộ nhưng chức năng được triển khai là công khai.


30

Trên thực tế - có một sự khác biệt lớn nếu bạn đang sử dụng sự phản chiếu; đặc biệt, Silverlight có thể rất khó chịu nếu bạn thử và truy cập các phương pháp nội bộ thông qua phản chiếu, ngay cả khi bạn đã có quyền truy cập. Tôi đã từng chứng kiến ​​những trường hợp phải công khai một phương thức để làm cho mã hoạt động trên Silverlight, mặc dù nó hoạt động trên .NET thông thường.

Bạn có thể nhận thấy điều tương tự khi tin tưởng một phần vào .NET thông thường.


3
Đây là những chi tiết bẩn thỉu mà tôi luôn quan tâm. Mặc dù vậy, nói chung nếu ai đó đang sử dụng phản chiếu để truy cập các thành viên ẩn trong lớp của tôi, tôi sẽ không lo lắng nếu điều đó gây khó khăn cho họ.
ScottS

1
@ScottS - đôi khi bạn đang phản ánh các loại của riêng mình - tức là nơi bạn thường có quyền truy cập vào phương thức nội bộ, nhưng đột nhiên bạn không thấy.
Marc Gravell

9

Nó sẽ tạo ra sự khác biệt khi bạn muốn lớp nội bộ của mình triển khai một giao diện. Phương thức là một triển khai của một số giao diện, sẽ phải là Công khai.


7

Bạn đã đúng, cả Phí và Fi sẽ có thể truy cập như nhau.

Từ Đặc tả ngôn ngữ CSharp 3.0, theo 3.5.2:

Miền khả năng truy cập của thành viên lồng nhau M được khai báo trong kiểu T trong chương trình P được định nghĩa như sau (lưu ý rằng bản thân M có thể là một kiểu):

• Nếu khả năng truy cập đã khai báo của M là công khai thì miền khả năng truy cập của M là miền khả năng truy cập của T.

Vì vậy, ngay cả khi Phí được khai báo là công khai, nó sẽ có thể truy cập được như Foo (tức là nội bộ).


3

Theo tài liệu msdn, lớp Foo của bạn sẽ không thể truy cập được bên ngoài assembly của bạn, vì vậy không có gì khác biệt khi đánh dấu các phương thức là nội bộ hoặc công khai; nó thậm chí không tạo ra sự khác biệt bằng cách sử dụng Attribute InternalsVibleTo


1

Tôi sẽ chỉ sử dụng các phương thức nội bộ nếu một lớp là nội bộ. trong trường hợp bạn thay đổi ý định và công khai lớp học, bạn chỉ có thể thực hiện thay thế văn bản và bạn đã hoàn tất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.