Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Thursday, September 3, 2009

Comma-separated Lists

One needs to convert a list of objects to comma-separated list of values sometimes. I often see StringBuilder used with some sort of loop. The most intellectual challenge is not to write comma after the last item; either there is some conditional expression in the loop step or some post processing is included to remove the last comma. Usually the result is consisting of several lines of code, perhaps too many for the purpose.

Users enthusiastic about Linq tend to involve Enumerable.Aggregate. Still String.Join may be the most straightforward method many times.

Monday, April 6, 2009

Selecting not nulls?

Having a collection IEnumerable<Nullable<T>> myCollection you can select values that are not null by calling myCollection.OfType<T>(). What is not so obvious is that calling myCollection.OfType<Nullable<T>>() would provide the same result.

This is because Enumerable.OfType<TResult> uses is internally to determine the type of item. It means, you can use Enumerable.OfType<T>() even for reference type T to get items that are not null.

Of course, I would prefer calling Where<T>(item => (item != null)) to calling OfType<T>() because the first call is much better in revealing its intention.

Tuesday, January 6, 2009

Collection Initializers

Collection initializers are very welcome in C# 3.0. Typing

new List<int> { 1, 2, 3 }

is of course much more convenient then typing

List<int> l = new List<int>();
l.Add(1);
l.Add(2);
l.Add(3);


However, when seeing examples (e.g. MSDN), one could think that you are limited in a single type in a collection initializer. But that is not true. You can use several Add overloads arbitrarily. Having the class

class MyCollection : IEnumerable
{
public void Add(string s) { ... }
public void Add(int i) { ... }
public void Add(SomeClass c) { ... }

//...
}

you can initialize it like this

new MyCollection
{
"something",
1,
2,
new SomeClass { ... },
"yet another string",
3
}

Wednesday, October 1, 2008

Boxing and arrays

There is one more catch with boxing (see also my former post Boxing and explicit conversions). Consider the code

public struct X
{
   public string Value { get; set; }
}

public void Fun()
{
   X x1 = new X { Value="original string 1" };
   X x2 = new X { Value="original string 2" };
   X[] array = new X[] { x1, x2 };

   array[0].Value = "modified string";
   //! x1 is not changed
}


I am occasionally amazed that x1 has "original string 1" on the line marked '!' although array[0] reads "modified string". Hell yes, that is because of boxing again. If X was classx1 would be changed, too.

Boxing and explicit conversions

Imagine you are writing a method that will process a number. You need to accept object as an argument.*) You know that you will accept integers. You have considered the usage of int and long, and you have chosen long since int can be safely converted to long. So you prepare something like

void ProcessNumber(object o)
{
   long number = (long)o; //!
   //do something with number
}


You test your method, and — surprise — you receive System.InvalidCastException on the line marked '!' when calling ProcessNumber(1). The problem is that boxing is involved, and the argument is not longer just int.

You can cast a boxed value only if it is of the very same type!

If it is not certain that you will receive single type in all calls, you had better use the appropriate method of the System.Convert class.

*) Consider accessing of properties via reflection.