Showing posts with label KnowDotNet. Show all posts
Showing posts with label KnowDotNet. Show all posts

Monday, March 14, 2011

KnowDotNet: String.Intern() and String.IsInterned()

Interning is a process where the compiler creates a pool of string references to literal strings in an application. You can use this feature to prevent re-allocation of the same string in memory. An interned string will stay in memory until the CLR has shutdown so this may be something to consider if memory usage is an issue/priority.

using System;
using System.Text;

namespace String_Intern_Test
{
    class Program
    {
        static void Main( string [] args ) {
            // Compile Time Interning
            var myInternedString = "This string is interned at compile time";
            Console.WriteLine( String.IsInterned( myInternedString ) 
                == null ? "NO" : "YES" ); // shows YES

            // Runtime Interning
            // IMPORTANT: Don't use StringBuilder to concatenate strings like this
            // I've used StringBuilder to avoid creating a string literal which would
            // be automatically interned.
            StringBuilder myStringBuilder = new StringBuilder();
            myStringBuilder.Append( "This is going to be" );
            myStringBuilder.Append( " interned soon!" );

            var myString = myStringBuilder.ToString();

            Console.WriteLine( String.IsInterned( myString ) 
                == null ? "NO": "YES" );  // shows NO
            String.Intern( myString );
            Console.WriteLine( String.IsInterned( myString ) 
                == null ? "NO" : "YES" );  // shows YES

        }
    }
}


In line 10 we create a string. The actual value of the string, ie. "This string is interned at compile time", is assigned for interning at compile time. The Console.WriteLine() will return YES meaning that the string was interned. Note a few things about line 11, 24 and 27: The strings are cast to objects so that the == operator tests equality of the references whereas strings redefine the behaviour of the == operator to do a comparison of the CONTENTS of the two strings.

From line 15 we have the start of a test where we programmatically intern a string. We use StringBuilder to construct a string to avoid the creation of a literal (or something that the compiler can figure out will be one whole string literal)

myString is eventually created from the StringBuilder contents... but note that this string is NOT interned (thus on line 24 you get a result of "NO". We then intern using String.Intern() and test again, this time we get YES on line 28.

String.Intern() will return the string if it is interned, if it doesn't exist it will intern the string and return the new interned string reference.

String.IsInterned() will return the string reference if it is interned, or null if it is not interned.

Now, when you have two string literals the compiler will intern the string and anywhere else you use that same string literal will refer, at runtime, to the same reference (or both strings will reference the same object.) To show this here is the above with a few alterations.

using System;
using System.Text;

namespace String_Intern_Test
{
    class Program
    {
        static void Main( string [] args ) {
            // Compile Time Interning
            var myInternedString = "This string is interned at compile time";
            Console.WriteLine( String.IsInterned( myInternedString )
                == null ? "NO" : "YES" );

            Test( myInternedString );
        }

        static void Test(string otherString) {
            var myInternedString2 = "This string is interned at compile time";

            Console.WriteLine((object) otherString 
                == (object) myInternedString2);
        }
    }
}
In this example line 20 will return True. otherString is actually the myInternedString string from the main() method. myInternedString is interned at compile time, and myInternedString2 will reference the same string in memory due to interning. Inside the Test() method we are comparing the references of these two strings and, as they are both exactly the same string literals, the compiler will intern the string and anywhere that string exists in the code will be loaded from the pool of strings. In other words anywhere the string literal exists will result in the same string reference being used.

KnowDotNet: String.Insert()

Another function I don't think I've ever used before... I tend to use String.Format() to insert values into strings or just concatenate them so I'm not sure how much I'll use this.

using System;

namespace String_Insert
{
    class Program
    {
        static void Main( string [] args ) {
            string interesting = "This is interesting";

            var veryInteresting = interesting.Insert( 8, "very " );

            Console.WriteLine( interesting );
            Console.WriteLine( veryInteresting );
        }
    }
}

We start off in line 8 creating a string and then in line 10 we insert the word "very " into that string using the Insert() method of the interesting object. This returns a new string with the words "This is very interesting".

Wednesday, March 9, 2011

KnowDotNet: String.Concat() and string contatenation

String.Concat() allows you to pass in multiple strings and it will create a new string big enough to contain the individual strings that you pass into the function. It then copies the individual strings into the new bigger strings.

So if you go like this:
using System;

class Tests
{
    static void Main( string [] args ) {
        string str1 = "This is a number: ";
        string str2 = 55.ToString();

        string newString = String.Concat( str1, str2 );
        Console.WriteLine( newString );
    }
}
You will get:
This is a number: 55
If you change the line that declares the newString variable to this:
string newString = str1 + str2;
The the IL code that is generated is exactly the same. String concatenation like that above is replaced by the compiler as a call to String.Concat(). In other words, the first example is fine; it just requires more typing. For more information on some of the interesting aspects of string concatenation then read this article called "Concatenating Strings Efficiently".

String.Concat() for Arrays of Strings.
Other String.Concat() overloads allows passing a string array as an argument. You can even pass arrays of objects; each on will have .ToString() called and the results concatenated.

using System;

class Tests
{
    static void Main( string [] args ) {
        string [] items = { "String1", "String2", "String3" };

        string newString = String.Concat( items );
        Console.WriteLine( newString );
    }
}

Monday, March 7, 2011

KnowDotNet: Index

I'm making this post as the master index of functions etc. that I put into the KnowDotNet series of posts. (so it could get long if I can keep this up) I'll break things up into classes (alphabetical with links to the functions underneath) Though if I try and find information on things I'll probably just use the search.

The tag for all of these posts is KnowDotNet

Introduction - This links to the post that describes why I'm doing this...

String Class
String.Concat() | Insert() | String.Intern() & String.IsInterned()String.IsNullOrEmpty() |  String.IsNullOrWhiteSpace()

Friday, March 4, 2011

KnowDotNet: String.IsNullOrEmpty

Do you ever find yourself in a situation where you need to know whether a string is Null or empty. The following gist shows some code that tests this.

(if you can't see the gist please click here)



The output of this code is as follows:

Is Null: True
Is Null: False
Is Null: False
Is Empty: False
Is Empty: True
Is Empty: True
IsNullOrEmpty: True
IsNullOrEmpty: True
IsNullOrEmpty: True

You will see that test1 is null and therefore not considered empty test2 and test3 have String.Empty or "" assigned and are both considered empty, but not null. In some scenario's you may not know necessarily what result from a function or somewhere else and you have to test for null AND equality to an empty string (or a string of Length == 0) Note: String.Empty is equal to ""

This function conveniently does both tests for you

KnowDotNet: String.IsNullOrWhiteSpace

So you don't care if a string has while space in it, all you want to do is ensure that a string doesn't have readable characters in it (or it's actually an empty string...

A simple example:
string myString = " ";
String.IsNullOrWhiteSpace( myString );

In the above example this returns true, as myString is not null and has only a space in it; no numbers or letters here!

Note that the IsNullOrWhileSpace() method is a static method on the String class.

Below is a gist containing several examples and their results. Next to the string variable declarations are comments showing what the code returns for the value of each string.

namespace String_IsNullOrWhitespace_Test
{
    using System;

    class Program
    {
        static void Main( string [] args ) {
            string test1 = null;            // True
            string test2 = String.Empty;    // True
            string test3 = "";              // True
            string test4 = " ";             // True
            string test5 = "\t";            // True
            string test6 = "\n";            // True
            string test7 = " a";            // False
            string test8 = "\0";            // False
            string test9 = "\b";            // False
            string test10 = "\a";           // False
           
            Console.WriteLine( String.IsNullOrWhiteSpace( test1 ) );
            Console.WriteLine( String.IsNullOrWhiteSpace( test2 ) );
            Console.WriteLine( String.IsNullOrWhiteSpace( test3 ) );
            Console.WriteLine( String.IsNullOrWhiteSpace( test4 ) );
            Console.WriteLine( String.IsNullOrWhiteSpace( test5 ) );
            Console.WriteLine( String.IsNullOrWhiteSpace( test6 ) );
            Console.WriteLine( String.IsNullOrWhiteSpace( test7 ) );
            Console.WriteLine( String.IsNullOrWhiteSpace( test8 ) );
            Console.WriteLine( String.IsNullOrWhiteSpace( test9 ) );
            Console.WriteLine( String.IsNullOrWhiteSpace( test10 ) );
        }
    }
}

Update: 2011-03-07 - Tarn Barford (@tarnacious) noted that this is a .Net 4 method. If you want similar functionality he mentioned that you can write an extension method... So for a bit more completeness here is one.

using System;
using System.Collections.Generic;
using System.Text;

namespace System
{
    public static class StringExtensionMethods
    {
        public static bool IsNullOrWhiteSpace(this string theString) {
            if ( theString != null ) {
                foreach ( char c in theString ) {
                    if ( Char.IsWhiteSpace( c ) == false )
                        return false;
                }
            }

            return true;
        }
    }
}

Then you can call the method like this:

Console.WriteLine( test1.IsNullOrWhiteSpace() );

Note that we can't make an equivalent static method using extension methods so it has to be used on a string reference.

KnowDotNet Introduction

This is the first in an potentially unending number of posts on classes, functions of the .Net Framework. It may include Visual Studio tips as I remember them or come across them.

The goal of this series is simply to make myself (and you if your interested) more familiar with what is available in the .Net framwork in the way of classes or function etc. In brainstorming a few ideas I've already come accross functions that I've not noticed before which would have made my life a little easier as a programmer.

Needless to say, this is probably going to be boring in some cases, but the .Net Framework has a massive amount of interesting and helful features, classes etc, that are impossible to use if you don't know they are there.

Just incase someone asks, the idea came about while listening to Dot Net Rocks in which they dedicate a few minutes at the beginning of each episode to something in dot net. I thought the idea had merit. I think that spending a few minutes a day looking at something that I've not used or even seen before, looking a bit closer at things I've used frequently even, can be of great benefit.

This is just an introduction, so keep your eye out for items with the tag KnowDotNet. The first few will probably be generally on the String class... It's a nice place to start :)