Blog Archive

Friday, June 30

Cast Delegate

Following my previous post, Ed went ahead and made a (C# 2.0-usable) Multicast-capable version:

public static T CastDelegate<T>(Delegate source)
    where T : class
    if (source == null)
        return null;

    Delegate[] delegates = source.GetInvocationList();
    if (delegates.Length == 1)
        return Delegate.CreateDelegate(typeof(T), delegates[0].Target, delegates[0].Method) as T;

    for (int i = 0; i < delegates.Length; i++)
        delegates[i] = Delegate.CreateDelegate(typeof(T), delegates[i].Target, delegates[i].Method);
    return Delegate.Combine(delegates) as T;

C# 3.0 and Delegate Conversion

System.Query defines a number of delegate types to help with query expressions. They follow the pattern of:

delegate T Func<T>();
delegate T Func<A0, T>(A0 arg0);
delegate T Func<A0, A1, T>(A0 arg0, A1 arg1);
// etc.

This is all well and good.

Certain methods in System.Query.Sequence take a parameter of Func<T, bool>. An example is Where<T>(this IEnumerable<T> source, Func<T, bool> predicate). Note that the underlying signatures of Func<T, bool> and Predicate<T> match.

Well it turns out that Delegates are kind of funky. For one thing, the Delegate class cannot be used as a generic type constraint. Also, conversion between compatible types of delegates isn't allowed (that is, you can't cast them).

That means that if one has a reference to an existing Predicate<T> one cannot use it as an argument to Where. I'm sure it won't come up much, because it's not often that one has a reference to a delegate without being able to reach the method that the delegate referrs to, but it could happen.

The best way I came up with to convert between two types of compatible delegates:

// CS0702: Constraint cannot be special class 'System.Delegate'
public static T ConvertTo<T>(this Delegate source)
    where T : class //, Delegate
    if (source.GetInvocationList().Length > 1)
        throw new ArgumentException("Cannot safely convert MulticastDelegate");

    return Delegate.CreateDelegate(typeof(T), source.Target, source.Method) as T;

This isn't great. Something like the following compiles just fine:

Predicate<int> isEven = n => n % 2 == 0;
MailAddress email = isEven.ConvertTo<MailAddress>();

Since Delegate is invalid as a type constraint, there's not really any way around it. I don't think that will ever cause any difficulty, though.

More subtly evil, however, is that conversion between incompatible delegates will appear to work fine at compile time, but result in a runtime error. Oh well. At least now I can do this:

int[] numbers = { 1, 2, 3, 4, 5 };
Predicate<int> isEven = n => n % 2 == 0;
foreach (var n in numbers.Where(isEven.ConvertTo<Func<int, bool>>()))

// Output:
// 2
// 4

… not that I ever would…

Update: the delegate conversion method has been extended/updated.

Thursday, June 29

Best Visual Studio Help Option

Best Visual Studio Help option I've unchecked, today: Tools > Options > General: Reuse topic window. Now hitting F1 in Visual studio is a lot more like my web browsing experience (external links open a new tab within Firefox). Ctrl-F4 or middle-click the tab to close it.

Update: to be clear, I'm talking about Help/Documentation Viewer/what used to be called MSDN; not actually Visual Studio itself.

Tuesday, June 27

Testing internal code

A few upfront assertions:

  1. Unit testing is good. For C# code I use NUnit (along with TestDriven.NET).
  2. Languages (including C#) have been designed with the internal keyword for a reason. There are legitimate uses for something that's accessible only within one's own assembly.
  3. These internal classes/methods are reasonable candidates for unit testing.

So, how do you test internal bits without compiling test code into your deliverable assembly?

It turns out that it's trivial (in the .NET 2.0 Framework): Friend Assemblies (see also).

Say you have two projects: MyCoolAssembly and MyCoolAssembly.UnitTests.

  1. In your MyCoolAssembly, open up the Properties/AssemblyInfo.cs.
  2. Add [assembly: InternalsVisibleTo("MyCoolAssembly.UnitTests")]

That's it! Now, MyCoolAssembly.UnitTests can access all of the internal classes/methods within MyCoolAssembly.

No conditional compilation symbols. No messy inner classes. Problem solved.

I found out about this useful attribute in CLR via C#, but Jay Bazuzi (whose blog I'd really like to read except that he apparently doesn't post anymore) had already blogged about this very usage back in September of 2004.

Thursday, June 22

Ruby's Enumerable mixin again

On the topic of Ruby's Enumerable mixin, it might be interesting to compare them to C# 2.0's Array/List<T> methods—static for Array, instance for List<T>—and 3.0's Standard Query Operators (System.Query namespace).

In the cases where C# does not support the method, I'd recommend following the link to the ruby docs. There are some rather interesting methods, and a lot can be learned from looking at what other languages support. In fact, some of these methods (each_slice, each_with_index) might be worth implementing as extension methods in C# (a trivial excercise left to the reader).

Ruby Enumerable C# 2.0 Array/List<T> methods* C# 3.0 System.Query
all? { |obj| block }
bool TrueForAll(Predicate<T> match) bool All<T>(this IEnumerable<T> source, Func<T, bool> predicate)
any? { |obj| block }
bool Exists(Predicate<T> match) bool Any<T>(this IEnumerable<T> source, Func<T, bool> predicate)
collect { |obj| block }
map { |obj| block}
List<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter) IEnumerable<S> Select<T, S>(this IEnumerable<T> source, Func<T, S> selector)
detect(ifnone = nil) { |obj| block }
find(ifnone = nil) { |obj| block }
T Find(Predicate<T> match) T First<T>(this IEnumerable<T> source, Func<T, bool> predicate)
T FirstOrDefault<T>(this IEnumerable<T> source, Func<T, bool> predicate)
each_cons(n) {...}
each_slice(n) {...}
each_with_index { |obj, index| block }
T[] ToArray<T>(this IEnumerable<T> source)
List<T> ToList<T>(this IEnumerable<T> source)
find_all { |obj| block }
select { |obj| block }
List<T> FindAll(Predicate<T> match) IEnumerable<T> Where(this IEnumerable<T> source, Func<T, bool> predicate)
grep(pattern) FindAll could certainly specify a predicate that applied a regular expression against each item of the collection. same for Where.
include?(obj) bool Contains(T item)
inject(initial) { |memo, obj| block }
inject { |memo, obj| block }
U Aggregate<T, U>(this IEnumerable<T> source, U seed, Func<U, T, U> func)
max / min
max / min { |a, b| block }
T Max/Min<T>(this IEnumerable<T> source), etc. Note that while there are a few overloads for this method, it looks like the delegates passed in merely provide value extraction. I don't see an overload where you can provide your own IComparer<T> (which is what the second Ruby method does)
partition { |obj| block }
reject { |obj| block } merely returns the collection of the inverse of find_all / select
sort { |a, b | block }
sort_by { |obj| block }
Sort(IComparer<T> comparison)
OrderedSequence<T, K> OrderBy/OrderByDescending/ThenBy/ThenByDescending(
  this IEnumerable<T> source, Func<T, K> keySelector)

OrderedSequence<T> OrderBy/OrderByDescending/ThenBy/ThenByDescending(
  this IEnumerable<T> source, Func<T, K> keySelector, IComparer<K> comparer)
zip(arg, ...)
zip(arg, ...) { |arr| block }

Enumerable mixin

I really like Ruby's Enumerable mixin. Methods like each_slice and each_with_index can inspire some really straightforward, elegant solutions.

Porting such a library to C# is trivial, but having to use the 2.0's verbose delegate syntax detracts from the coolness a bit. Using 3.0's lambda expressions on the other hand…

Okay, blogger's template is obviously not well suited to preformatted text. I should try and fix that sometime…

Ruby and C#


numbers = [1, 2, 3, 4, 5]
is_even = proc { |n| (n.modulo 2).zero? }

( {|n| "#{n} #{is_even[n] ? 'is' : 'is not'} even"}).each {|summary| puts summary}

C# 3.0

int[] numbers = {1, 2, 3, 4, 5};
Predicate<int> isEven = n => n % 2 == 0;

Array.ForEach(numbers, n => Console.WriteLine("{0} {1} even", n, isEven(n) ? "is" : "is not"));

or if you prefer...

Array.ForEach(numbers, n => Console.WriteLine("{0} {1} even", n, isEven(n) ? "is" : "is not"));

numbers.Each(n => Console.WriteLine("{0} {1} even", n, isEven(n) ? "is" : "is not"));

// elsewhere
public static class EnumerableExtensions
  public static void Each<T>(this IEnumerable<T> collection, Action<T> action)
    foreach (T item in collection)

C# and Ruby

Searching Google for C# Ruby sure yields some interesting articles. I hope to add to the mix in the coming weeks as I play around with the C# 3.0/LINQ May CTP.

Stay tuned…