The InnerText property of an XmlNode will never return an interned string. The text string in the node has been retrieved from a file (or some other stream), and will not automatically be interned by the framework or .NET runtime. Depending on the implementation, the InnerText property might return the same string each time, or a new string might be created for each get. But the string instance will not be the same for different nodes, even if the text is the same.
The documentation for string.Intern is clearly a bit confusing. I'm not sure what they mean with a "programmatically" created literal string. A literal string is stored within the assembly and includes the strings within quotation marks in your program.
An interned string can never be garbage collected, so interning strings loaded from a file could cause serious memory usage problems. I strongly recommend that you don't intern strings loaded from an XML-file, unless you know that it is a common string that will be used over the life-time of the application.
Instead I recommend that you take another approach to avoid duplicate instances.
After we wrote the duplicate instances detector we of course tested it on the profiler itself, and we found a lot of duplicate instances. To avoid the duplicate instances we wrote two container classes that help us avoid the duplicate instances: SingleValueContainer and WeakSingleValueContainer. I have attached a zip-file that includes slightly modified versions of these containers. You may use them in your project if you wish. Just note that have I modified them from our original code and the modifications have not been thoroughly tested yet. Use them at your own risk
The SingleValueContainer is suitable to use when you have a clearly defined "region" where you want to avoid duplicate instances. This can for instance be when you open an XML-file or other document that includes a lot of duplicate string or other duplicate instances.
Code: Select all
private void LoadTransactionItems()
SingleValueContainer<string> commonStrings = new SingleValueContainer<string>();
XmlNode xmlNode = ...;
list.Add( new TransactionItem(commonStrings[xmlNode.InnerText]) );
The SingleValueContainer indexer provides a single copy of the provided element (based on IEqualityComparer) similar to the string.Intern method (but the container handles any class, not just strings). However, as soon as the container is cleared or GCed, the elements in the container are also eligible for collection.
The WeakSingleValueContainer is similar to the SingleValueContainer, but it only keeps a weak reference to the elements, so there's no need to explicitly clear the container. However, the overhead is significantly higher for the WeakSingleValueContainer, since a weak GC handle is created for each unique item. You can use the WeakSingleValueContainer when the "region" is not as clearly defined and/or when you expect to have many duplicates and only a few unique instances.
I hope this helps. Reply to this post if you need any additional information or help on how to use the containers.