2011-06-21 54 views
9

Trong lớp String có phương thức IsInterned(). Tôi không bao giờ sử dụng phương pháp này. Xin hãy giúp tôi hiểu cách sử dụng tốt nhất của phương pháp này.Mục đích của String.IsInterned là gì?

+2

Không hài lòng với tài liệu chính thức tại msft? http://msdn.microsoft.com/en-us/library/system.string.isinterned.aspx – tzup

+5

@tzup: Các tài liệu cho biết chức năng hoạt động, không phải khi bạn sử dụng nó. – Gabe

Trả lời

3

Có thể sử dụng một lần nếu bạn muốn khóa giá trị chuỗi.

Trong điều sau đây:

string s = //get it from somewhere, e.g. a web request 
lock (s){ 
//do something 
} 

có một vấn đề, bởi vì có thể có hai yêu cầu khác nhau cho cùng một chuỗi, nhưng cả hai đều nhập mã bảo vệ. Điều này là do có thể có hai đối tượng chuỗi khác nhau có cùng giá trị.

Tuy nhiên, có một cái gì đó gọi là intern pool, đó là một bảng có chứa một ví dụ duy nhất của một số chuỗi (tất cả các literals là có ví dụ).

Bạn có thể sử dụng nó để làm các công việc khóa:

string s = //get it from somewhere, e.g. a web request 
lock (string.Intern(s)){ 
//do something 
} 

Chức năng này sẽ trả về một tham chiếu đến một chuỗi trong hồ bơi thực tập, trong đó có giá trị tương tự như s, như vậy là an toàn cho khóa.

Chức năng IsIntern chỉ cần kiểm tra xem tham chiếu bạn đang nắm giữ có phải là tham chiếu đến chuỗi trên hồ bơi thực tập hay không.

+6

Không bao giờ khóa trên một chuỗi. Chuỗi là tên miền nhanh, tức là cùng một thể hiện chuỗi có thể truy cập được từ nhiều miền ứng dụng, đặc biệt là khi được thực tập. Kết quả sẽ là một chủ đề có thể chờ đợi một khóa được phát hành trong một appdomain không liên quan ... hiệu ứng rất khó chịu. – MaLio

+0

Khóa trên chuỗi.Intern sẽ kết hợp khóa! – usr

1

Chuỗi ký tự trong C# được tập trung (nghĩa là chúng được lưu trữ trong một hồ bơi thực) để cho mỗi lần xuất hiện của chữ chỉ có một trường hợp. Nếu bạn đang tạo ngôn ngữ của riêng mình (ví dụ: một số hệ thống tập lệnh), bạn có thể sử dụng IsInterned và Intern để mang lại số tiền tương tự.

2

Hãy tham khảo các bài của Eric, tôi nghĩ rằng đây là tốt nhất mà trong Intern được giải thích

+3

Chuỗi "IsInterned" không xuất hiện trong bài viết đó. – usr

0

Có một cái nhìn tại this. Có thực sự là một trường hợp sử dụng trong chủ đề đó.

7

Hãy xem xét việc thực tập là một tối ưu hóa; nó giao dịch giảm một số phẩm chất mong muốn để tăng số lượng khác. Trong thực tập cụ thể có những phẩm chất tốt sau đây:

  1. Bộ nhớ không bị lãng phí trên các chuỗi trùng lặp.
  2. So sánh bình đẳng giữa các chuỗi được biết là cả hai được thực tập là cực kỳ nhanh.
  3. So sánh bình đẳng giữa các chuỗi xảy ra được thực tập vẫn nhanh hơn nhiều so với khi chúng không được tập trung.
  4. So sánh khác nhận được lợi ích hiệu suất trong một số trường hợp.

Nó có những phẩm chất xấu sau đây:

  1. Strings không thu gom rác thải thường xuyên (nếu có), do bộ nhớ có thể được khai hoang được sử dụng trên dây mà không bao giờ được nhìn thấy một lần nữa, hoặc cho một thời gian rất dài. (Intern tất cả các dây của bạn và bạn có thể kết thúc với việc sử dụng bộ nhớ thực sự khó chịu).

Là một tối ưu hóa, chúng tôi sử dụng nó ở những phẩm chất tốt ngoài cân nặng hoặc nơi chất lượng xấu không giữ được (nếu chúng ta biết chuỗi sẽ tồn tại trong suốt thời gian tồn tại của ứng dụng dù sao, hoặc biết nó sẽ được sử dụng nhiều lần, sau đó phần xấu không giữ).

Và bởi cùng một mã thông báo, chúng tôi không sử dụng nó khi những phẩm chất xấu sẽ vượt quá cân nặng. (Hầu hết thời gian).

IsInterned() có thể được sử dụng để tìm điểm bán phần.

Cân nhắc tôi có một tài sản chuỗi Name:

public string Name { get; set; } 

Hãy nói rằng tôi biết rằng nó phổ biến để tìm kiếm đối tượng với một Name nhất định, hoặc để cố gắng tìm các đối tượng với cùng Name hoặc làm nhiều so sánh bình đẳng trên đó. HOẶC Giả sử tôi biết sẽ có rất nhiều đối tượng khác với cùng một số Name. Hoặc cả hai.

Trong những trường hợp này tôi có thể xem xét thực tập:

private string _name; 
public string Name 
{ 
    get { return _name; } 
    set { _name = string.Intern(value); } 
} 

Tất nhiên, cho dù đây là một ý tưởng tốt hay không phụ thuộc vào những phẩm chất tốt và xấu của thực tập nêu trên.

In-giữa việc sử dụng và không sử dụng là khả năng:

private string _name; 
public string Name 
{ 
    get { return _name; } 
    set { _name = string.IsInterned(value) ?? value; } 
} 

đây nếu chuỗi value đã được thực tập nội trú sau đó chúng tôi xuống-bên thực tập đã tại nơi làm việc và chúng tôi không chịu đựng được nữa , vì vậy chúng tôi tận dụng lợi thế của nó. Nhưng nếu value không phải là đã được interned thì chúng tôi chỉ sử dụng nó như là.

Đây cũng là một tối ưu hóa, tối ưu hóa cho một trường hợp khác. Nó chỉ mang lại lợi ích nếu một số lượng hợp lý các giá trị nhìn thấy có khả năng được thực hiện bởi một số mã khác (hoặc vì chúng khớp với các chữ trong assembly), nếu không nó chỉ lãng phí thời gian để tra cứu. Nó có lẽ ít thường hữu ích hơn Intern() mà lần lượt ít hữu ích hơn là chỉ sử dụng các chuỗi và bỏ qua việc thực tập, nhưng điều đó cho thấy một thời điểm khi nó có thể hữu ích.

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