- Posted by Shay Friedman on January 16, 2010
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.
- Posted by Shay Friedman on October 5, 2009
A while ago I wrote a post about using Generic CLR classes from IronRuby. This time I’ll share with you its less intuitive friend – using generic CLR methods from IronRuby.
As a result of Ruby being a duck-typed language which works with types implicitly, generics is not really needed. The whole language is generic… This is why using generic CLR types might become a bit odd for the language. Nonetheless, this fact will not stop us. The price to pay in order to enjoy Ruby in the .Net framework is worth it! :)
Anyway, assuming we have the following C# class defined in file sample.dll:
namespace ClassLibrary1
{
public class Class1
{
public string Test<T>(T param)
{
return param.ToString();
}
}
}
In order to use it with a specific type, you need to do two things – get the generic method object (by using the method method) and provide it with the type via the special of method. For example, the next code invokes Test with a string and pass it “Shay Friedman”:
require "sample.dll"
sample = ClassLibrary1::Class1.new
sample.method(:test).of(String).call("Shay Friedman") # returns "Shay Friedman"
And that’s all there is to know.
All the best,
Shay.
- Posted by Shay Friedman on September 9, 2009
When I was playing around with Silverlight and IronRuby, I ran into a problem with data binding and IronRuby objects. This post is to let you know about it and hand you the workaround as well.
The Problem
You have an IronRuby class. You fill it with data and set it as the data context of your Silverlight element.
The result: the values are not presented on the Silverlight page.
Detailed steps to reproduce:
1. Create an IronRuby class. For example:
class Person
attr_accessor :full_name
def initialize(full_name)
self.full_name = full_name
end
end
2. Create an instance of that class and set it as the data_context of an element:
shay = Person.new "Shay Friedman"
@root.data_context = shay
3. Set the element to present the data:
<StackPanel>
<TextBlock>You name is </TextBlock>
<TextBlock Text="{Binding full_name}"/>
</StackPanel>
4. Run the page – nothing is shown.
The Reason
With the help of Jimmy Schementi I’ve figured out what the problem was. Silverlight 3.0 elements can only do reflection-based data binding. IronRuby objects are based on ICustomTypeDesciptor, which means that the attributes cannot be read using reflection. Bummer.
The Workaround
Instead of using an IronRuby class, use a CLR class. This means that in order to make it work, the work flow should be as follows:
1. Create a C#/VB.Net class. For example (assume this appears in “person.dll”):
class Person
{
public string FullName { get; set; }
public Person(string fullName)
{
FullName = fullName;
}
}
2. Create an instance of that class in IronRuby and set it as the data_context of an element:
require "person.dll"
shay = Person.new("Shay Friedman")
@root.data_context = shay
3. Set the element to present the data:
<StackPanel>
<TextBlock>You name is </TextBlock>
<TextBlock Text="{Binding FullName}"/>
</StackPanel>
4. Run the page – everything works as expected.
All the best,
Shay.