Il meccanismo di “string interning” nel .Net Micro Framework

Consideriamo la seguente semplicissima applicazione console in C# …

 static void Main(string[] args)
 {
   string s1 = "Hello world";
   string s2 = "Hello world";

   Console.WriteLine(s1.Equals(s2));
   Console.WriteLine(ReferenceEquals(s1, s2));
   Console.WriteLine(s1 == s2);

   string s3 = String.Intern(Console.ReadLine());

   Console.WriteLine(s1.Equals(s3));
   Console.WriteLine(ReferenceEquals(s1, s3));
   Console.WriteLine(s1 == s3);

   Console.ReadKey();
 }

Il cui output è il seguente …

string_intern_net

Come sappiamo il metodo Equals() e l’operatore “==” verificano che se le due stringhe contengono lo stesso valore pur avendo un reference diverso (s1 ed s2), per cui è ovvio il risultato “True”. Ma come mai la ReferenceEquals() continua a fornire “True” e non “False” considerando che i due riferimenti sono diversi ?

Bene ! Essi non sono diversi in realtà !

Il .Net Framework fornisce un meccanismo di “string interning” ossia un pool all’interno del quale gestisce le stringhe che hanno il medesimo valore evitando di allocare inutilmente ulteriore memoria. Per questo motivo, s1 ed s2 sono in realtà il medesimo riferimento !

E’ ovvio che, quando una stringa viene acquisita dall’esterno ciò non accade ed è quindi necessario chiedere esplicitamente al framework di cercare la stringa acquisita prima nel pool interno ed eventualmente allocarne una nuova se essa non esiste … questo è l’obiettivo dell’istruzione String.Intern().

Proviamo ora ad eseguire il medesimo codice (a meno di alcune modifiche) sul .Net Micro Framework …

 public static void Main()
 {
    string s1 = "Hello world";
    string s2 = "Hello world";
 
    Debug.Print(s1.Equals(s2).ToString());
    Debug.Print(ReferenceEquals(s1, s2).ToString());
    Debug.Print((s1 == s2).ToString());

    string s3 = String.Intern("Hello world");
    
    Debug.Print(s1.Equals(s3).ToString());
    Debug.Print(ReferenceEquals(s1, s3).ToString());
    Debug.Print((s1 == s3).ToString());
 }

con il seguente risultato …

string_intern_netmf

In questo caso il ReferenceEquals() ci conferma che i due reference sono diversi nel primo caso ma anche utilizzando String.Intern() … come mai ?

Il motivo è semplice … il .Net Micro Framework non supporta il meccanismo di “string interning” e non fornisce un pool interno di stringhe e la risposta è come sempre nell’implementazione nativa. Guardando nel file String.cs, troviamo :

 public static String Intern(String str)
 {
   // We don't support "interning" of strings. So simply return the string.
   return str;
 }

 public static String IsInterned(String str)
 {
   // We don't support "interning" of strings. So simply return the string.
   return str;
 }

Un esplicito commento ci dice che questa funzionalità non è supportata !

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s