IronShay

Ironing code, geek t-shirts and even presentations!

NAVIGATION - SEARCH

Use .NET Built-in Methods to Save Time and Headaches

During our everyday programming tasks we run into several repetitive code blocks that after the 20th time you implement them become really annoying. The worst case is to re-implement these code blocks every time, and the better case is to create a central class library with helper classes and methods. However, a large amount of these tasks can be achieved easily with built-in .NET methods.

In this post I will go through several repetitive code blocks and show you how to implement them using built-in .NET method. If you want to add your suggestions, comment! I’ll add your suggestions to the post periodically.

Disclaimer: I’m sure some of the code blocks I use in the NOT Recommended sections can be written much better. These code blocks are here just for demonstration purposes.

Code Block #1 – Check string for nullity or emptiness

NOT Recommended

str = "something"
if (str == null || str == String.Empty)
{
	// Oh no! the string isn't valid!
}

Recommended

str = "something"
if (String.IsNullOrEmpty(str))
{
	// Oh no! the string isn't valid!
}

Code Block #2 – Check string for nullity or emptiness (spaces only string is invalid too)

NOT Recommended

str = "something"
if (str == null || str.Trim() == String.Empty)
{
	// Oh no! the string isn't valid!
}

Recommended (C# 4.0 Only)

str = "something"
if (String.IsNullOrWhiteSpace(str))
{
	// Oh no! the string isn't valid!
}

Code Block #3 – Copy an Array

NOT Recommended

string[] source = new string[] { "a", "b", "c" };
string[] dest = new string[3];
for (int i=0; i < source.Length; i++)
{
	dest[i] = source[i];
}

Recommended

string[] source = new string[] { "a", "b", "c" };
string[] dest = new string[3];
Array.Copy(surce, dest, source.Length);

Code Block #4 – Check if a char is a digit

NOT Recommended

char c = '1';
if (c == '1' || c == '2' || c == '3' ||
	c == '4' || c == '5' || c == '6' ||
	c == '7' || c == '8' || c == '9' ||
	c == '0')
{
	// It's a digit!
}

Recommended

char c = '1';
if (Char.IsDigit(c))
{
	// It's a digit!
}

Code Block #5 – Combine Paths

NOT Recommended

string folder = @"C:\MyDir";
string file = "MyFile.docx";
// Combine to make a path
string path = folder + @"\" + file;

Recommended

string folder = @"C:\MyDir";
string file = "MyFile.docx";
// Combine
string path = System.IO.Path.Combine(folder, file);

Code Block #6 – Get file extension out of a file path

NOT Recommended

string path = @"C:\MyDir\MyFile.docx";
string extension = path.Substring(path.LastIndexOf("."));

Recommended

string path = @"C:\MyDir\MyFile.docx";
string extension = System.IO.Path.GetExtension(path);

Code Block #7 – Get MyDocuments Path

NOT Recommended

// Probably some nasty stuff here

Recommended

Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

Code Block #8 – Check if object is of a specific type

NOT Recommended

object obj = "str";
if (obj.GetType() == typeof(String))
{
	// It's a string!
}

Recommended

object obj = "str";
if (obj is String)
{
	// It's a string!
}

As Adrian Aisemberg has pointed out, these samples are not entirely the same. The is keyword will return true also if obj is of a derivative type of String (in this sample).

Code Block #9 – Set default enum value

NOT Recommended

public class MyClass
{
	private enum Sample 
	{
		A,
		B,
		C
	}
	static Sample s = Sample.B; // Set default value explicitly
	public static void Run()
	{	
		Console.WriteLine(s); // Prints B
	}
}

Recommended

public class MyClass
{
	private enum Sample 
	{
		A,
		B = 0, // Make B the default value
		C
	}
	static Sample s; // Default value will be used
	public static void Run()
	{	
		Console.WriteLine(s); // Prints B
	}
}

Code Block #10 – Check if a string starts with another string

NOT Recommended

string str = "Hello World";
if (str.Substring(0, 5) == "Hello")
{
	// String starts with Hello!			
}

Recommended

string str = "Hello World";
if (str.StartsWith("Hello"))
{
	// String starts with Hello!		
}

Code Block #11 – Convert list of items of one type to a list of items of a different type

NOT Recommended

List<int> list = new List<int>(new[] { 1, 2, 3, 4, 5 });
List<string> convertedList = new List<string>();
foreach (int item in list)
{
	convertedList.Add(item.ToString());
}

Recommended

List<int> list = new List<int>(new[] { 1, 2, 3, 4, 5 });
List<string> convertedList = list.ConvertAll<string>(Convert.ToString);

Code Block #12 – Check if a string contains a number and get the number

NOT Recommended

string str = "4";

int num = 0;
bool success = false;
try 
{
	num = Convert.ToInt32(str);
	success = true;
}
catch
{
	success = false;
}

if (success)
{
	// Do something with the number
}

Recommended

string str = "4";

int num = 0;
if (Int32.TryParse(str, out num))
{
	// Do something with the number
}

Code Block #13 – Writing a string to a file (courtesy of Yaron Naveh)

NOT Recommended

const string str = "put me in a file";
const string file = @"c:\logs\file.txt";

var fs = new FileStream(file, FileMode.Create);          
var sw = new StreamWriter(fs);
sw.Write(str);

sw.Close();
fs.Close();

Recommended

const string str = "put me in a file";
const string file = @"c:\logs\file.txt";

File.WriteAllText(file, str);

Code Block #14 – Pick value if not null and a different on if it is (courtesy of Abhishek)

NOT Recommended

string input = "sdfds";
string result = null;
if (input == null)
{
	result = "Input is null!";
}
else
{
	result = input;
}

Recommended

string input = "sdfds";
string result = input ?? "Input is null!";

 

This is it for now. If you have more, comment and I’ll add your suggestions to the list (with credits).

All the best,
Shay.

kick it on DotNetKicks.com Shout it


Comments (18) -

Israel Adrian Aisemberg

Cool! Thanks man!

One thing:

obj.GetType() == typeof(String)
vs.
obj is String

The two are not the same thing. Suggesting the second over the first might lead to an error.

Consider this:
    class Base
    {
    }

    class Derive : Base
    {
    }


var d = new Derive();

var a = d.GetType() == typeof(Base);  // False
var b = (d is Base);  // True

Obviously, it will work for strings (for being sealed), but...

Thanks!

Reply

Good post.
Adrian is right of course. The "not recommended" could be replaced with the use of Type.IsAssignableFrom (and would stay "not recommended in this specific situation).
However, it could be helpful in other places.

Itai.

Reply

Following is very helpful tip as well. Works for all nullable/reference types.

string s1 = null;
string s2 = s1??"s1 is null";

Reply

I agree with and follow all of these - just one comment:
For number 12:
int num = 0;
if (Int32.TryParse(str, out num))

Since TryParse accepts an "out" parameter, you should not assign the value of zero to num prior to calling it - TryParse always assigns a value, success or failure (assigns zero if unsuccesful).

Reply

This list is very helpful. I just want to comment on Code Block #12. As Joe mentioned in his comment that TryParse always assigns a value equivalent to the number contained in s, if the conversion succeeded, or zero if the conversion failed. What if numeric 0 is a legitimate value? I think IsNumeric() can be a good alternative to that.

Reply

That was very helpful.. Thanks

Reply

"Not Recommended" folderpath example is missing.

Reply

Helpful post, Thanks

Reply

One small (pedantic) comment about your second example where you transform (str == null || str.Trim() == String.Empty) into str.IsNullOrWhiteSpace().  IsNullOrWhiteSpace uses Char.IsWhitespace to decide if a character in the string is considered white space or not.  Trim() uses subtly different fixed list of whitespace characters (defined in the documentation: msdn.microsoft.com/en-us/library/t97s7bs3.aspx).  There are white space characters that IsNullOrWhiteSpace will say "true" on where Trim() would return a non empty string.

Reply

Thank you

it s very good

Reply

According to what Irfan said:
I just want to comment on Code Block #12. As Joe mentioned in his comment that TryParse always assigns a value equivalent to the number contained in s, if the conversion succeeded, or zero if the conversion failed. What if numeric 0 is a legitimate value? I think IsNumeric() can be a good alternative to that.

Since Int32.TryParse is:
public static bool TryParse(
    string s,
    out int result
)

Then zero isn't a problem - if there was an error in conversion, the function itself just returns false, so it can be determined, whether the conversion succeeded on not.

Reply

Good Article.

Regarding, Code Block #13:

File.WriteAllText(file, str); will overwrite the existing contents of a file. So we can't use this method for logging kind of activities.

File.AppendAllText(file, str); will append the specified string.

Cheers

Reply

Nice list, but I spottet a flaw at #9:

If you do it like that both Sample.A and Sample.B are zero!

Try it for yourself:

   Sample s1 = Sample.A;
   Sample s2 = Sample.B;
   Sample s3 = Sample.C;

   int i1 = (int)s1; //0
   int i2 = (int)s2; //0
   int i3 = (int)s3; //1


That's because Enum fields allways beginn with 0 and increment with each new field.

another approach would be to just write

     public enum Sample  
     {  
         B,
         A,  
         C
     }  

Smile

Reply

Thanks! Very useful!

Reply

It might be nice if you could explain why these things are better.

For #11 I also like the Linq format:
list.Select(i => i.ToSting())

Reply

Instead of any "manual" code to check if debug mode is enabled, just use:

HttpContext.Current.IsDebuggingEnabled

Reply

United States Kevin Hanson

Typo in Codeblock #3 "Recommended":

Array.Copy(surce, dest, source.Length);

should be:

Array.Copy(source, dest, source.Length);

Reply

TryParse accepts an "out" parameter, you should not assign the value of zero to num prior to calling it - TryParse always assigns a value, success or failure (assigns zero if unsuccesful).

Reply

Pingbacks and trackbacks (4)+

Add comment