Sử dụng thực tế cho từ khóa nội bộ trên mạng trong C #


420

Bạn có thể giải thích cách sử dụng thực tế cho internaltừ khóa trong C # không?

Tôi biết rằng công cụ internalsửa đổi giới hạn quyền truy cập vào hội đồng hiện tại, nhưng tôi nên sử dụng nó khi nào và trong trường hợp nào?

Câu trả lời:


379

Các lớp / phương thức của trình trợ giúp hoặc tiện ích mà bạn muốn truy cập từ nhiều lớp khác trong cùng một cụm, nhưng bạn muốn đảm bảo mã trong các cụm khác không thể truy cập.

Từ MSDN (thông qua archive.org):

Việc sử dụng phổ biến truy cập nội bộ là trong phát triển dựa trên thành phần vì nó cho phép một nhóm các thành phần hợp tác theo cách riêng tư mà không bị lộ với phần còn lại của mã ứng dụng. Ví dụ, một khung để xây dựng giao diện người dùng đồ họa có thể cung cấp các lớp Điều khiển và Biểu mẫu hợp tác sử dụng các thành viên có quyền truy cập nội bộ. Vì các thành viên này là nội bộ, họ không được tiếp xúc với mã đang sử dụng khung.

Bạn cũng có thể sử dụng công cụ sửa đổi nội bộ cùng với InternalsVisibleTothuộc tính cấp độ lắp ráp để tạo các cụm "bạn bè" được cấp quyền truy cập đặc biệt vào các lớp bên trong lắp ráp đích.

Điều này có thể hữu ích cho việc tạo ra các hội đồng thử nghiệm đơn vị mà sau đó được phép gọi các thành viên nội bộ của hội đồng sẽ được thử nghiệm. Tất nhiên không có hội đồng nào khác được cấp mức truy cập này, vì vậy khi bạn phát hành hệ thống của mình, việc đóng gói được duy trì.


8
Thuộc tính InternalsVisibleTo là một trợ giúp tuyệt vời. Cảm ơn bạn.
erict

33
Cảm giác của tôi là từ lúc bạn cần nội bộ, có gì đó không đúng thiết kế ở đâu đó. IMHO, người ta có thể sử dụng OO thuần túy để giải quyết tất cả các vấn đề. Tại thời điểm này, tôi đang nhìn chằm chằm vào việc sử dụng nội bộ một phần triệu trong nguồn .NET Framework, chặn đường tôi tận dụng những thứ họ sử dụng. Thông qua việc sử dụng nội bộ, họ đã tạo ra một khối nguyên khối có tính mô đun bề ngoài, nhưng bị phá vỡ khi bạn cố gắng cách ly công cụ. Ngoài ra, an ninh không phải là một đối số, như có sự phản ánh đối với việc giải cứu.
Nỗi sợ hãi tuyệt vọng

26
@GrimaceofDespair: Hãy để tôi thêm một bình luận diagreeing ở đây. Cá nhân tôi thấy nội bộ là một phiên bản rất hữu ích của công cụ sửa đổi "công khai" trong các giải pháp đa dự án lớn. Việc thêm công cụ sửa đổi này vào một lớp trong tiểu dự án của tôi sẽ cấm "sử dụng ngẫu nhiên" lớp này bởi các tiểu dự án khác trong giải pháp và giúp tôi có thể buộc sử dụng đúng thư viện của mình. Nếu sau này tôi cần phải thực hiện một số thao tác tái cấu trúc, tôi sẽ không phải tự hỏi mình "chờ đã, nhưng tại sao anh chàng đó lại đi và tạo một thể hiện của lớp Point mà tôi chỉ cần cho mục đích riêng của mình trong tính toán cụ thể này"?
KT.

3
Nói cách khác, nếu mọi người sẽ dựa vào phần bên trong của SmtpClient, và tại một thời điểm, một lỗi đã được phát hiện ở đó, .NET sẽ gặp vấn đề nghiêm trọng để sửa lỗi đó, thậm chí có thể giữ nó trong một thời gian dài. Tôi nhớ rằng tôi đã đọc một bài viết thú vị một lần, trong đó mô tả thời lượng mà các nhà phát triển Windows phải đi để giữ "khả năng tương thích với lỗi" với tất cả các chương trình cũ sử dụng các tính năng và lỗi bên trong khác nhau. Lặp lại lỗi này với .NET không có ý nghĩa.
KT.

13
Tôi nghĩ rằng nội bộ là CÁCH hữu ích hơn công khai. Lần duy nhất bạn sử dụng công khai là khi bạn nói rõ ràng "Ở đây, người dùng - Tôi đang cung cấp một chức năng hữu ích cho bạn sử dụng." Nếu bạn đang viết một ứng dụng thay vì thư viện người dùng, mọi thứ sẽ là nội bộ vì bạn không cố gắng cung cấp cho mọi người bất kỳ chức năng nào để gọi ra bên ngoài. Nếu bạn đang viết thư viện người dùng, thì chỉ những chức năng hữu ích mà bạn mong muốn cung cấp cho người dùng, duy trì, hỗ trợ và giữ cho đến khi hết thời gian mới được công khai. Nếu không, làm cho nó nội bộ.
Darrell Plank

85

Nếu Bob cần BigImportantClass thì Bob cần phải nhờ những người sở hữu dự án A đăng ký để đảm bảo rằng BigImportantClass sẽ được viết để đáp ứng nhu cầu của anh ta, được kiểm tra để đảm bảo đáp ứng nhu cầu của anh ta, được ghi nhận là đáp ứng nhu cầu của anh ta, và đó là một quá trình sẽ được đưa ra để đảm bảo rằng nó sẽ không bao giờ bị thay đổi để không còn đáp ứng nhu cầu của anh ta nữa.

Nếu một lớp là nội bộ thì nó không phải trải qua quá trình đó, giúp tiết kiệm ngân sách cho Dự án A mà họ có thể chi cho những thứ khác.

Quan điểm của nội bộ không phải là nó làm cho cuộc sống của Bob trở nên khó khăn. Đó là nó cho phép bạn kiểm soát những lời hứa đắt giá mà Project A đang thực hiện về các tính năng, tuổi thọ, khả năng tương thích, v.v.


5
Làm cho cảm giác hoàn hảo. Chỉ ước rằng chúng tôi có khả năng ghi đè các thành viên nội bộ, bởi vì tất cả chúng ta đều đồng ý người lớn ở đây.
cwallenpoole

6
@EricLippert Không hoàn toàn như tôi muốn nói. Nếu tôi thừa hưởng mã được biên dịch có "nội bộ" trong đó, tôi sẽ bị kẹt, phải không? Không có cách nào đơn giản để nói với trình biên dịch "Không, nhà phát triển khác đã nói dối bạn. Thay vào đó bạn nên tin tưởng tôi" trừ khi tôi sử dụng sự phản chiếu.
cwallenpoole

11
@cwallenpoole: Nếu bạn đang sử dụng mã được viết bởi những kẻ nói dối viết mã mà bạn không thích thì hãy ngừng sử dụng mã của họ và viết mã của riêng bạn mà bạn thích hơn.
Eric Lippert

2
@EricLippert Điều đó được cho là tặc lưỡi, tôi không có ý xúc phạm. (Tôi hầu như chỉ cố gắng xác nhận rằng tôi là SOL trong những trường hợp như vậy).
cwallenpoole

5
@cwallenpoole: Tôi không bị xúc phạm ít nhất. Tôi đang đưa ra lời khuyên tốt nếu bạn thấy mình bị mắc kẹt trong tình huống không may đó.
Eric Lippert

60

Một lý do khác để sử dụng nội bộ là nếu bạn làm xáo trộn nhị phân của mình. Obfuscator biết rằng an toàn khi xáo trộn tên lớp của bất kỳ lớp bên trong nào, trong khi tên của các lớp công khai không thể bị xáo trộn, vì điều đó có thể phá vỡ các tham chiếu hiện có.


4
Pff. Nhìn vào mã byte với trình phân tách vẫn sẽ làm cho nó khá rõ ràng những gì mã làm gì. Obfuscators hầu như không phải là một công cụ răn đe nhẹ đối với bất kỳ ai thực sự cố gắng vào bên trong. Chưa bao giờ nghe nói về một hacker đã dừng lại chỉ vì anh ta không nhận được bất kỳ tên chức năng hữu ích nào.
Nyerguds

28
Vì vậy, bạn không khóa cửa khi bạn ngủ, bởi vì bạn chưa bao giờ nghe nói về một tên trộm dừng lại bởi một khóa?
Sergio

4
Đó là lý do tại sao tôi tranh giành tên lớp và tên biến trong mã nguồn. Bạn có thể tìm ra PumpStateComparator là gì, nhưng bạn có thể đoán LpWj4mwe là gì không? #jobsecurance (Tôi không làm điều này và làm ơn đừng thực sự làm điều này, dân mạng.)
Slothario

32

Nếu bạn đang viết một DLL đóng gói một tấn chức năng phức tạp vào một API công khai đơn giản, thì nội bộ của Cameron được sử dụng cho các thành viên lớp không được công khai.

Ẩn sự phức tạp (hay còn gọi là đóng gói) là khái niệm chính của công nghệ phần mềm chất lượng.


20

Từ khóa nội bộ được sử dụng nhiều khi bạn đang xây dựng một trình bao bọc cho mã không được quản lý.

Khi bạn có thư viện dựa trên C / C ++ mà bạn muốn DLLImport, bạn có thể nhập các hàm này dưới dạng hàm tĩnh của một lớp và biến chúng thành nội bộ, vì vậy người dùng của bạn chỉ có quyền truy cập vào trình bao bọc của bạn chứ không phải API gốc để không thể lộn xộn với bất cứ điều gì. Các hàm là tĩnh bạn có thể sử dụng chúng ở mọi nơi trong cụm, cho nhiều lớp bao bọc bạn cần.

Bạn có thể xem Mono.Cairo, đây là một trình bao bọc xung quanh thư viện cairo sử dụng phương pháp này.


12

Được điều khiển bởi "sử dụng công cụ sửa đổi nghiêm ngặt như bạn có thể" quy tắc Tôi sử dụng nội bộ ở mọi nơi tôi cần truy cập, giả sử, phương thức từ một lớp khác cho đến khi tôi rõ ràng cần truy cập nó từ một hội đồng khác.

Vì giao diện lắp ráp thường hẹp hơn so với tổng các giao diện lớp của nó, có khá nhiều nơi tôi sử dụng nó.


3
Nếu bạn "sử dụng công cụ sửa đổi nghiêm ngặt như bạn có thể" thì tại sao không riêng tư?
R. Martinho Fernandes

6
Vì private quá nghiêm ngặt khi các thuộc tính / phương thức lớp phải được truy cập bên ngoài lớp và các trường hợp khi chúng phải được truy cập từ một asse khác, bly không thường xuyên như vậy.
Ilya Komakhin

11

Tôi thấy nội bộ được sử dụng quá mức. bạn thực sự không nên chỉ hiển thị một số chức năng nhất định cho các lớp nhất định mà bạn sẽ không cho người tiêu dùng khác.

Điều này theo tôi phá vỡ giao diện, phá vỡ sự trừu tượng. Điều này không có nghĩa là không bao giờ nên sử dụng nó, nhưng một giải pháp tốt hơn là tái cấu trúc sang một lớp khác hoặc được sử dụng theo một cách khác nếu có thể. Tuy nhiên, điều này có thể không phải lúc nào cũng có thể.

Những lý do nó có thể gây ra vấn đề là nhà phát triển khác có thể bị buộc tội xây dựng một lớp khác trong cùng một tổ hợp mà bạn đang có. Có nội bộ làm giảm sự rõ ràng của sự trừu tượng, và có thể gây ra vấn đề nếu bị lạm dụng. Nó sẽ là vấn đề tương tự như khi bạn công khai nó. Lớp khác đang được xây dựng bởi nhà phát triển khác vẫn là người tiêu dùng, giống như bất kỳ lớp bên ngoài nào. Trừu tượng hóa lớp và đóng gói không chỉ để bảo vệ cho / từ các lớp bên ngoài, mà cho bất kỳ và tất cả các lớp.

Một vấn đề khác là rất nhiều nhà phát triển sẽ nghĩ rằng họ có thể cần phải sử dụng nó ở nơi khác trong hội đồng và đánh dấu nó là dù sao đi nữa, mặc dù lúc đó họ không cần đến nó. Một nhà phát triển khác sau đó có thể nghĩ rằng nó có để lấy. Thông thường bạn muốn đánh dấu riêng tư cho đến khi bạn có một nhu cầu dứt khoát.

Nhưng một số điều này có thể chủ quan, và tôi không nói rằng nó không bao giờ nên được sử dụng. Chỉ cần sử dụng khi cần thiết.


Tôi thường xây dựng các đối tượng miền mà chúng có các thành viên nên công khai cho các đối tượng miền khác trong cùng một cụm. Tuy nhiên, những thành viên tương tự này KHÔNG nên có sẵn cho mã máy khách nằm ngoài hội đồng. Đối với những tình huống như thế này, 'nội bộ' là rất phù hợp.
Rock Anthony Johnson

8

Tôi thấy một điều thú vị vào một ngày khác, có thể là tuần, trên một blog mà tôi không thể nhớ. Về cơ bản tôi không thể tin tưởng vào điều này nhưng tôi nghĩ nó có thể có một số ứng dụng hữu ích.

Giả sử bạn muốn một lớp trừu tượng được nhìn thấy bởi một hội đồng khác nhưng bạn không muốn ai đó có thể kế thừa từ nó. Bịt kín sẽ không hoạt động vì nó trừu tượng vì một lý do, các lớp khác trong hội đồng đó được thừa hưởng từ nó. Riêng tư sẽ không hoạt động vì bạn có thể muốn khai báo một lớp Parent ở đâu đó trong hội đồng khác.

không gian tên Base.Assugging
{
  lớp trừu tượng công cộng Phụ huynh
  {
    khoảng trống trừu tượng bên trong someMethod ();
  }

  // Điều này hoạt động tốt vì nó trong cùng một hội đồng.
  lớp học công cộng ChildWithin: Phụ huynh
  {
    ghi đè nội bộ void someMethod ()
    {
    }
  }
}

không gian tên Another.Assugging
{
  // Kaboom, vì bạn không thể ghi đè một phương thức nội bộ
  lớp học công cộng ChildOutside: Phụ huynh
  {
  }

  Kiểm tra lớp học công cộng 
  { 

    //Bình thường
    Cha mẹ riêng _parent;

    Kiểm tra công khai ()
    {
      //Vẫn khỏe
      _parent = new ChildWithin ();
    }
  }
}

Như bạn có thể thấy, nó thực sự cho phép ai đó sử dụng lớp Parent mà không thể kế thừa từ đó.


7

Ví dụ này chứa hai tệp: Hội1.cs và Hội2.cs. Tệp đầu tiên chứa một lớp cơ sở nội bộ, BaseClass. Trong tệp thứ hai, một nỗ lực khởi tạo BaseClass sẽ tạo ra lỗi.

// Assembly1.cs
// compile with: /target:library
internal class BaseClass 
{
   public static int intM = 0;
}

// Assembly1_a.cs
// compile with: /reference:Assembly1.dll
class TestAccess 
{
   static void Main()
   {  
      BaseClass myBase = new BaseClass();   // CS0122
   }
}

Trong ví dụ này, sử dụng cùng các tệp bạn đã sử dụng trong ví dụ 1 và thay đổi mức độ truy cập của BaseClass thành công khai . Đồng thời thay đổi mức độ truy cập của IntM thành viên thành nội bộ . Trong trường hợp này, bạn có thể khởi tạo lớp, nhưng bạn không thể truy cập thành viên nội bộ.

// Assembly2.cs
// compile with: /target:library
public class BaseClass 
{
   internal static int intM = 0;
}

// Assembly2_a.cs
// compile with: /reference:Assembly1.dll
public class TestAccess 
{
   static void Main() 
   {      
      BaseClass myBase = new BaseClass();   // Ok.
      BaseClass.intM = 444;    // CS0117
   }
}

nguồn : http://msdn.microsoft.com/en-us/l Library / 7c5ka91b (VS.80) .aspx


6

Khi bạn có các phương thức, các lớp, v.v ... cần truy cập trong phạm vi của hội đồng hiện tại và không bao giờ nằm ​​ngoài nó.

Ví dụ, một DAL có thể có ORM nhưng các đối tượng không được tiếp xúc với lớp nghiệp vụ, tất cả các tương tác phải được thực hiện thông qua các phương thức tĩnh và truyền vào các tham số cần thiết.


6

Một cách sử dụng nội bộ rất thú vị - tất nhiên với thành viên nội bộ chỉ bị giới hạn trong hội đồng mà nó được tuyên bố - sẽ nhận được chức năng "bạn bè" ở một mức độ nào đó. Một thành viên bạn bè là một cái gì đó chỉ có thể nhìn thấy đối với một số hội đồng khác bên ngoài hội đồng mà nó tuyên bố. C # không có hỗ trợ tích hợp cho bạn bè, tuy nhiên CLR thì có.

Bạn có thể sử dụng InternalsVisibleToAttribution để khai báo hội đồng bạn bè và tất cả các tham chiếu từ bên trong hội đồng bạn bè sẽ coi các thành viên nội bộ của hội đồng khai báo của bạn là công khai trong phạm vi của hội nghị bạn bè. Một vấn đề với điều này là tất cả các thành viên nội bộ có thể nhìn thấy được; bạn không thể chọn và chọn.

Một cách sử dụng tốt cho InternalsVisibleTo là đưa các thành viên nội bộ khác nhau đến một tổ hợp thử nghiệm đơn vị, do đó loại bỏ các nhu cầu về công việc phản xạ phức tạp xung quanh để kiểm tra các thành viên đó. Tất cả các thành viên nội bộ có thể nhìn thấy không phải là vấn đề quá lớn, tuy nhiên thực hiện phương pháp này sẽ làm hỏng giao diện lớp của bạn khá nhiều và có khả năng phá hỏng sự đóng gói trong hội đồng khai báo.


5

Theo quy tắc, có hai loại thành viên:

  • bề mặt công cộng : hiển thị từ một tổ hợp bên ngoài (công khai, được bảo vệ và được bảo vệ bên trong): người gọi không đáng tin cậy, vì vậy cần xác thực tham số, tài liệu phương thức, v.v.
  • bề mặt riêng tư : không thể nhìn thấy từ một cụm bên ngoài (lớp riêng và nội bộ hoặc lớp bên trong): người gọi thường được tin cậy, do đó, xác thực tham số, tài liệu phương thức, v.v. có thể bị bỏ qua.

4

Giảm tiếng ồn, càng ít loại bạn tiếp xúc với thư viện của bạn càng đơn giản. Tamper Proofing / Security là một thứ khác (mặc dù Reflection có thể giành chiến thắng trước nó).


4

Các lớp bên trong cho phép bạn giới hạn API của hội đồng của bạn. Điều này có lợi ích, như làm cho API của bạn đơn giản hơn để hiểu.

Ngoài ra, nếu một lỗi tồn tại trong lắp ráp của bạn, sẽ có ít khả năng sửa lỗi giới thiệu một thay đổi đột phá. Nếu không có các lớp nội bộ, bạn sẽ phải cho rằng việc thay đổi bất kỳ thành viên nào của lớp sẽ là một thay đổi đột phá. Với các lớp bên trong, bạn có thể giả định rằng sửa đổi các thành viên công khai của họ chỉ phá vỡ API nội bộ của hội đồng (và bất kỳ hội đồng nào được tham chiếu trong thuộc tính InternalsVisibleTo).

Tôi thích có sự đóng gói ở cấp độ lớp và ở cấp độ lắp ráp. Có một số người không đồng ý với điều này, nhưng thật tuyệt khi biết rằng chức năng này có sẵn.


2

Tôi có một dự án sử dụng LINQ-to-SQL cho back-end dữ liệu. Tôi có hai không gian tên chính: Biz và Dữ liệu. Mô hình dữ liệu LINQ sống trong Dữ liệu và được đánh dấu là "nội bộ"; không gian tên Biz có các lớp công khai bao quanh các lớp dữ liệu LINQ.

Vì vậy, có Data.Client, và Biz.Client; cái sau phơi bày tất cả các thuộc tính có liên quan của đối tượng dữ liệu, ví dụ:

private Data.Client _client;
public int Id { get { return _client.Id; } set { _client.Id = value; } }

Các đối tượng Biz có một hàm tạo riêng (để buộc sử dụng các phương thức của nhà máy) và một hàm tạo bên trong trông như thế này:

internal Client(Data.Client client) {
    this._client = client;
}

Điều đó có thể được sử dụng bởi bất kỳ lớp nghiệp vụ nào trong thư viện, nhưng giao diện người dùng (UI) không có cách nào truy cập trực tiếp vào mô hình dữ liệu, đảm bảo rằng lớp nghiệp vụ luôn hoạt động như một trung gian.

Đây là lần đầu tiên tôi thực sự sử dụng internalnhiều và nó tỏ ra khá hữu ích.


2

Có những trường hợp có ý nghĩa để làm cho các thành viên của các lớp internal. Một ví dụ có thể là nếu bạn muốn kiểm soát cách các lớp được khởi tạo; giả sử bạn cung cấp một số loại nhà máy để tạo các thể hiện của lớp. Bạn có thể tạo hàm tạo internal, để nhà máy (nằm trong cùng một tổ hợp) có thể tạo các thể hiện của lớp, nhưng mã bên ngoài cụm đó thì không thể.

Tuy nhiên, tôi không thể thấy bất kỳ điểm nào với việc tạo ra các lớp học hoặc thành viên internalmà không có lý do cụ thể, chỉ cần tạo ra chúng publichoặc privatekhông có lý do cụ thể.


1

điều duy nhất tôi từng sử dụng từ khóa nội bộ là mã kiểm tra giấy phép trong sản phẩm của mình ;-)


1

Một cách sử dụng từ khóa nội bộ là để hạn chế quyền truy cập vào các triển khai cụ thể từ người dùng lắp ráp của bạn.

Nếu bạn có một nhà máy hoặc một số vị trí trung tâm khác để xây dựng các đối tượng, người dùng lắp ráp của bạn chỉ cần xử lý giao diện chung hoặc lớp cơ sở trừu tượng.

Ngoài ra, các hàm tạo bên trong cho phép bạn kiểm soát vị trí và khi nào một lớp công khai được khởi tạo.


1

Làm thế nào về điều này: thông thường, bạn không nên để lộ một đối tượng Danh sách cho người dùng bên ngoài của một hội đồng, thay vào đó để lộ một IEnumerable. Nhưng việc sử dụng một đối tượng List bên trong assembly sẽ dễ dàng hơn nhiều, bởi vì bạn có được cú pháp mảng và tất cả các phương thức List khác. Vì vậy, tôi thường có một thuộc tính nội bộ hiển thị Danh sách sẽ được sử dụng bên trong hội đồng.

Bình luận được hoan nghênh về phương pháp này.


@Samik - bạn có thể vui lòng giải thích thêm, "thông thường, bạn không nên để lộ một đối tượng Danh sách cho người dùng bên ngoài của một hội đồng, thay vì để lộ một IEnumerable." Tại sao vô số được ưa thích?
Howiecamp

1
@Howiecamp: Chủ yếu là do IEnumerable cung cấp quyền truy cập chỉ đọc vào danh sách, trong khi nếu bạn để lộ danh sách trực tiếp, nó có thể được sửa đổi bởi các máy khách (như xóa các phần tử, v.v.), có thể là ngoài ý muốn.
Samik R

Ngoài ra, việc hiển thị Danh sách hoặc IList sẽ tạo ra một hợp đồng mà bạn sẽ luôn cho phép (ví dụ) truy cập ngẫu nhiên nhanh chóng vào dữ liệu. Nếu một ngày nào đó bạn quyết định thay đổi phương thức của mình để sử dụng một bộ sưu tập khác hoặc hoàn toàn không có bộ sưu tập nào (lợi nhuận mang lại), bạn sẽ phải tạo Danh sách chỉ để trả về giá trị hoặc phá vỡ hợp đồng bằng cách thay đổi loại trả về của phương thức. Sử dụng một loại trả lại ít cụ thể hơn cho bạn sự linh hoạt.

1

Hãy nhớ rằng bất kỳ lớp nào được xác định là publicsẽ tự động hiển thị trong intellisense khi ai đó nhìn vào không gian tên dự án của bạn. Từ góc độ API, điều quan trọng là chỉ hiển thị cho người dùng dự án của bạn các lớp mà họ có thể sử dụng. Sử dụng internaltừ khóa để ẩn những thứ họ không nên thấy.

Nếu Big_Important_Classdự án A của bạn được dự định sử dụng bên ngoài dự án của bạn, thì bạn không nên đánh dấu nó internal.

Tuy nhiên, trong nhiều dự án, bạn sẽ thường có các lớp thực sự chỉ dành cho sử dụng bên trong một dự án. Ví dụ, bạn có thể có một lớp chứa các đối số cho một lời gọi luồng được tham số hóa. Trong những trường hợp này, bạn nên đánh dấu chúng như internalthể không vì lý do nào khác ngoài việc bảo vệ bản thân khỏi sự thay đổi API ngoài ý muốn.


Vậy tại sao không sử dụng riêng tư thay thế?
Tù nhân ZERO

1
Các privatetừ khóa chỉ có thể được sử dụng trên lớp hoặc cấu trúc được định nghĩa trong một lớp học hoặc struct. Một lớp được định nghĩa trong một không gian tên chỉ có thể được khai báo publichoặc internal.
Matt Davis

1

Ý tưởng là khi bạn thiết kế một thư viện, chỉ các lớp được dự định sử dụng từ bên ngoài (bởi các khách hàng của thư viện của bạn) nên được công khai. Bằng cách này bạn có thể ẩn các lớp

  1. Có khả năng thay đổi trong các bản phát hành trong tương lai (nếu chúng là công khai, bạn sẽ phá vỡ mã máy khách)
  2. Vô dụng với khách hàng và có thể gây nhầm lẫn
  3. Không an toàn (vì vậy sử dụng không đúng cách có thể phá vỡ thư viện của bạn khá tệ)

Vân vân.

Nếu bạn đang phát triển các giải pháp đường phố hơn là sử dụng các yếu tố nội bộ thì tôi đoán không quan trọng, bởi vì thông thường các khách hàng sẽ liên lạc thường xuyên với bạn và / hoặc truy cập vào mã. Họ là khá quan trọng cho các nhà phát triển thư viện mặc dù.


-7

Khi bạn có các lớp hoặc phương thức không phù hợp với Mô hình hướng đối tượng, thực hiện các công cụ nguy hiểm, cần được gọi từ các lớp và phương thức khác dưới sự kiểm soát của bạn và bạn không muốn cho phép bất kỳ ai khác sử dụng .

public class DangerousClass {
    public void SafeMethod() { }
    internal void UpdateGlobalStateInSomeBizarreWay() { }
}

Bạn đang cố nói điều gì vậy? Nó không rõ ràng lắm. Ít nhất là không phải với tôi.
pqsk

Đồng ý với @pqsk
Khan bất thường
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.