New Minimod: FluentGenerics–Interacting with Generic Types and Type-Definitions

Sometimes, from a concrete type, you need to find out if it implements a specific generic type or interface, and even more interesting, which concrete type arguments it uses in it’s implementation.

Since this information can be “hidden” somewhere in the type hierarchy, I created some helper extension methods that help finding this information and released them as a Minimod. What is a Minimod?

It can answer these simple questions:

Is List<Int32> an IEnumerable<T>? yes
If it is, what are the type parameters? Int32

Is Dictionary<Int32,String> an IDictionary<TKey,TValue>? yes
If it is, what are the type parameters? Int32,String

This is the test/example code generating them:

[Test]
public void PrintExamples()
{
    printExample(typeof(List<int>), typeof(IEnumerable<>));
    printExample(typeof(Dictionary<int, string>), typeof(IDictionary<,>));
}

private static void printExample(Type type, Type genTypeDef)
{
    bool isOfGenericType = type.IsOfGenericType(genTypeDef);

    Console.WriteLine("Is {0} an {1}? {2}",
                      type.GetPrettyName(),
                      genTypeDef.GetPrettyName(),
                      isOfGenericType ? "yes." : "no.");

    if (isOfGenericType)
    {
        Console.WriteLine("If it is, what are the type parameters? "
                          + type.GetGenericArgumentsFor(genTypeDef)
                                .Select(_ => _.GetPrettyName())
                                .JoinStringsWith(", "));
    }
}

Summary

The Minimod adds to System.Type the following extension methods:

  • bool IsOfGenericType(this Type type, Type genericTypeDefinition)
  • Type[] GetGenericTypesFor(this Type type, Type genericTypeDefinition)
  • Type GetGenericTypeFor(this Type type, Type genericTypeDefinition)
  • Type[] GetGenericArgumentsFor(this Type type, Type genericTypeDefinition)

Get it!

It is published to Nuget as a Minimod: NuGet gallery

Other minimods are also available there: Packages – NuGet gallery

Original source code is found at: minimod/minimods – GitHub

Advertisement

Turtles are Reptiles, right?

While writing an article about co- and contravariance in .NET I stumbled over some funny C# behaviors.

Given a simple domain model of animals (Reptile is base of Snake and Turtle), will this actually work?

And if not, what will happen? Will it even compile?

Reptile[] reptiles = new[]
  {
    new Snake("Leo"), 
    new Snake("Lucy")
  };

reptiles[0] = new Turtle("Platschi");

Quite obvious, still odd. 🙂

GREAT! Thanks for the answers!

I think @thinkbeforecoding had the best answer. Justin Chase, Björn Rochel and Stefan Lieser also got it right.

Here is what happens:

  1. It compiles!
  2. The type inference will infer a Snake[] from new[] because all elements are Snake.
  3. The Snake array will then be implicitly casted to the Reptile array reptiles because C# supports covariance for Array element types.
  4. Line 7 also compiles fine. But the covariance support is unsafe, hence read-only. The Snake-Array behind the scenes can’t handle Turtles.
  5. A ArrayTypeMismatchException is thrown at runtime.

In C# 4.0 there will not be safe variance for Arrays either. There can never be safe co- and contra-variance for read-write-interfaces or types, because you need co-variance for reading (out) and contra-variance for writing (in).

24. November 2009: Ko- und Kontravarianz bei Bonn-to-Code

Beim nächsten Bonn-to-Code-Usergroup-Treffen halte ich einen Kurzvortrag zu Ko- und Kontravarianz in C#.

Sneak Peak

Eines der meistbegrüßten Features aus .NET 4 und gleichzeitig eines der am wenigsten verstandenen. Leicht dahergesagt, dass Argumente von Methoden und Delegates schon immer kontravariant waren. Und dass in C# 4.0 jetzt noch sichere Ko- und Kontravarianz für generische Typparameter hinzukommt. Und weil man das mit Ko- und Kontra so schnell verwechselt heißt es jetzt einfach "out" und "in". Oder war das andersrum? Nicht ganz sicher?

Ich kann schonmal so viel verraten, dass ich mich sogar an selbstgemalten Bildchen versuchen werde. Außerdem kommen Tiger und Schlangen vor!

image

Weitere Themen

  • M und die "Oslo" Plattform Benjamin Gopp
  • Kurzvortrag: Umgang mit .NET Assemblies Thomas van Veen

Mehr Informationen

Test helpers #1: Repetition Extensions and Scenario

While writing tons of tests I would like to share some of my helper classes here. My first ones are for doing simple performance measurements (not too accurate) and repeating actions.

Code:

using (new Scenario("Sum of all squares from 1 to 100"))
    Console.WriteLine("Sum is: {0}", 100.Times(x => x * x).Sum());

using (new Scenario("Print all squares from 1 to 10"))
    10.Times(x => Console.WriteLine("{0} * {0} = {1}", x, x*x));

Output:

>> {1} - Sum of all squares from 1 to 100
Sum is: 1000000
<< {1} 15ms for Sum of all squares from 1 to 100
>> {2} - Print all squares from 1 to 10
1 * 1 = 1
2 * 2 = 4
3 * 3 = 9
4 * 4 = 16
5 * 5 = 25
6 * 6 = 36
7 * 7 = 49
8 * 8 = 64
9 * 9 = 81
10 * 10 = 100
<< {2} 13ms for Print all squares from 1 to 10
&#91;/sourcecode&#93;</pre></div>

<h2>Repetition Extensions</h2>

<div style="display:inline;float:none;margin:0;padding:0;" id="scid:4CF65DF0-5960-450c-B43D-AE27EAE72175:64baee98-e9e4-4a96-9dc8-a453ac2997da" class="wlWriterEditableSmartContent"><pre>
public static class RepetitionExtensions
{
    public static IEnumerable<int> Times(this int count)
    {
        for (int i = 1; i <= count; i++)
        {
            yield return i;
        }
    }

    public static void Times(this int count, Action<int> action)
    {
        foreach (var i in count.Times())
        {
            action(i);
        }
    }

    public static void Times(this int count, Action action)
    {
        count.Times((i) => action());
    }

    public static TResult[] Times<TResult>(this int count, Func<TResult> action)
    {
        var results = new List<TResult>(count);
        count.Times(() => results.Add(action()));
        return results.ToArray();
    }

    public static TResult[] Times<TResult>(this int count, Func<int, TResult> action)
    {
        var results = new List<TResult>(count);
        count.Times(() => results.Add(action(count)));
        return results.ToArray();
    }

    public static IEnumerable<TResult> LazyTimes<TResult>(this int count, Func<TResult> action)
    {
        foreach (var i in count.Times())
        {
            yield return action();
        }
    }

    public static IEnumerable<TResult> LazyTimes<TResult>(this int count, Func<int, TResult> action)
    {
        foreach (var i in count.Times())
        {
            yield return action(i);
        }
    }
}

Scenario

public class Scenario : IDisposable
{
    private readonly string message;
    private readonly Stopwatch stopwatch = new Stopwatch();
    private static int nextUid = 0;
    private int uid = nextUid+=1;

    public Scenario(string message)
    {
        this.message = message;
        stopwatch = new Stopwatch();
        Console.WriteLine(">> {{{0}}} - {1}", uid, message);
        stopwatch.Start();
    }

    public void Dispose()
    {
        stopwatch.Stop();
        var elapsed = stopwatch.Elapsed;
        
        var elements = new List(4);

        if (elapsed.Days != 0)
            elements.Add(string.Format("{0} days", elapsed.Days));

        if (elapsed.Hours != 0)
            elements.Add(string.Format("{0} hours", elapsed.Hours));

        if (elapsed.Minutes != 0)
            elements.Add(string.Format("{0} minutes", elapsed.Minutes));

        if (elapsed.Seconds != 0 && elapsed.Milliseconds != 0)
            elements.Add(string.Format("{0}.{1}s", elapsed.Seconds, elapsed.Milliseconds));

        else if (elapsed.Seconds != 0)
            elements.Add(string.Format("{0}s", elapsed.Seconds));

        else if (elapsed.Milliseconds != 0)
            elements.Add(string.Format("{0}ms", elapsed.Milliseconds));

        var formatted = new StringBuilder();
        if (elements.Count > 0)
        {
            if (elements.Count > 1)
            {
                formatted.Append(string.Join(", ", elements.Take(elements.Count - 1).ToArray()));
                formatted.Append(" and ");
            }

            formatted.Append(elements.Last());
        }
            

        Console.WriteLine(string.Format("<< {{{0}}} {1} for {2}", uid, formatted, message));
    }
}
[/sourcecode]

Behind the scenes of the C# yield keyword

After reading the great article about the code-saving yield keyword “Give way to the yield keyword” by Shay Friedman I thought it could be interesting to know how the yield keyword works behind the scenes.

…it doesn’t really end the method’s execution. yield return pauses the method execution and the next time you call it (for the next enumeration value), the method will continue to execute from the last yield return call. It sounds a bit confusing I think… (ShayF)

By using yield return within a method that returns IEnumerable or IEnumerator the language feature is activated.

Note: IEnumerable is kind of a stateless factory for Enumerators. IEnumerable.GetEnumerator() is thread safe and can be called multiple times, while the returned stateful Enumerator is just a helper for enumerating contained values once. By contract IEnumerator offers a Reset() method, but many implementations just throw a NotSupportedException.

Lets create an enumerator method that yields some Fibonacci nubmers.

public class YieldingClass
{
    public IEnumerable<int> GetFibonachiSequence()
    {
        yield return 1;
        yield return 2;
        yield return 3;
        yield return 5;
    }
}

Note: Yield is not a feature of the .Net runtime. It is just a C# language feature which gets compiled into simple IL code by the C# compiler.

The compiler now generates a inner class with following signature (Reflector + some renaming):

[CompilerGenerated]
private sealed class YieldingEnumerator : 
   IEnumerable<object>, IEnumerator<object>
{
    // Fields
    private int state;
    private int current;
    public YieldingClass owner;
    private int initialThreadId;

    // Methods
    [DebuggerHidden]
    public YieldingEnumerator(int state);
    private bool MoveNext();
    [DebuggerHidden]
    IEnumerator<int> IEnumerable<int>.GetEnumerator();
    [DebuggerHidden]
    IEnumerator IEnumerable.GetEnumerator();
    [DebuggerHidden]
    void IEnumerator.Reset();
    void IDisposable.Dispose();

    // Properties
    object IEnumerator<object>.Current 
    { [DebuggerHidden] get; }

    object IEnumerator.Current 
    { [DebuggerHidden] get; }
}

The original method GetFibonachiSequence() only returns a new instance of the YieldingEnumerator, passing the initial state –2 as well as itself as the owner.

Each enumerator holds a state indicating:

  • -2: Initialized as Enumerable. (Not yet an Enumerator)
  • -1: Closed
  • 0: Initialized as Enumerator. 
    If a new Enumerator is requested on the same instance, GetEnumerator() returns another new instance of YieldingEnumerator.
  •  1-n: Index of the yield return in the original GetFibonachiSequence()method. In case of nested enumerators or other more complex scenarios one yield return consumes more than one index.

The content of GetFibonachiSequence() is translated into YieldingEnumerator.MoveNext().

In our very simple scenario the code looks like this:

bool MoveNext()
{
    switch (state)
    {
        case 0:
            state = -1;
            current = 1;
            state = 1;
            return true;

        case 1:
            state = -1;
            current = 2;
            state = 2;
            return true;

        case 2:
            state = -1;
            current = 3;
            state = 3;
            return true;

        case 3:
            state = -1;
            current = 5;
            state = 4;
            return true;

        case 4:
            state = -1;
            break;
    }
    return false;
}

Quite easy, isn’t it?

So far we easily could have created the classes and methods used to enable the yield keyword ourselves, too.

But in more complex scenarios Microsoft does some tricks, which won’t compile as C# – at least not how Reflector translates the resulting IL code.

Lets have a look at some code with a nested enumeration…

foreach(int i in new int[] {1, 2, 3, 5, 8})
{
    yield return i;
}

This compiles into:

private bool MoveNext()
{
    try
    {
        switch (state)
        {
            case 0:
                state = -1;
                state = 1;
                this.values = new int[] { 1, 2, 3, 5, 8 };
                this.currentPositionInValues = 0;
                while (this.currentPositionInValues < this.values.Length)
                {
                    current_i = this.values[this.currentPositionInValues];
                    current = current_i;
                    state = 2;
                    return true;
                Label_007F:
                    state = 1;
                    this.currentPositionInValues++;
                }
                this.Finally2();
                break;

            case 2:
                goto Label_007F;
        }
        return false;
    }
    fault
    {
        this.System.IDisposable.Dispose();
    }
}
[/sourcecode]

Now the states 1 and 2 are used to indicate whether the enumerator actually is at some point (2), or wether it is trying to retrieve the next value (1).

Two things would not compile:

  • goto Label_007F is used to jump back into the iteration over int[] values. The C# goto statement is not able to jump into another statements context. But in IL this is totally valid as a while statement in MSIL is nothing but some gotos either.
  • The fault is proper MSIL, but not supported in C#. Basically it acts as a finally which just is executed in case of an error.

Attention: As in anonymous delegates, parameters as well as local and instance variables are passed to the YieldingEnumerator only once. Read this great post on this: Variable Scoping in Anonymous Delegates in C#

Thanks for your attention!

kick it on DotNetKicks.com

Use Path.Combine to avoid ugly program failures!

I’ve so often seen people combining paths like this:

string path = basePath + "\\" + filename;

Sometimes they use Path.DirectorySeparatorChar or even check wether basePath or filename already contains. The program then fails with exceptions like "could not find file c:\Program Files\MyProggie\\settings.xml" or even worse files like MyProggiesettings.xml are created, just because the person configuring the program isn’t aware of how and where to use "\".

This what System.IO.Path.Combine(string, string) does for you:

  • It validates both paths. They can be null or empty, but if they contain invalid path chars, an argument exception is thrown.
  • It uses Path.DirectorySeparatorChar to combine, but will never end up having two separators or none.
  • It takes only the second path if it is absolute, so you never get paths like "c:\data\d:\data\logs\myfile.xml"
  • If one of the paths is null or empty, the other one is returned.

Simple combinations

If the second path is relative, it will get combined with the first path.

  • Path.Combine("abc", "file.xml") => "abc\file.xml"
  • Path.Combine("abc\", "file.xml") => "abc\file.xml"
  • Path.Combine("c:\abc\", "file.xml") => "c:\abc\file.xml"
  • Path.Combine("c:\abc\", "data\file.xml") => "c:\abc\data\file.xml"
  • Path.Combine("", "data\file.xml") => "data\file.xml"
  • Path.Combine("c:\abc", "") => "c:\abc"

Absolute second path

If the second path is absolute, the first one will be ignored. (See also Path.IsPathRooted(string))

  • Path.Combine("c:\abc", "\file.xml") => "\file.xml"

    (if the second path starts with the DirectorySeparatorChar it is also treated as absolute!)
  • Path.Combine("c:\abc", "c:\file.xml") => "c:\file.xml"

Example Usage

For NT Services the root directory often is "c:\Windows\System32", so if you want to store something relatively, you should combine it with AppDomain.CurrentDomain.BaseDirectory.

So if you want to write something to a configured file within your application you could code it like this:

var file = ConfigurationManager.AppSettings["MyXmlFile"];
if (string.IsNullOrEmpty(file))
    throw new ConfigurationErrorsException(
                      "Missing app setting: 'MyXmlFile'.");

var filePath = Path.Combine(
                    AppDomain.CurrentDomain.BaseDirectory, 
                    file);

using (var writer = new StreamWriter(filePath))
{
    // write something to your file ...
}

kick it on DotNetKicks.com

Free .Net Ambient Context Pattern Implementation

For Geeks: Skip explanations, just show the solution!

Well, many of us already utilize this pattern – just without knowing it has a name. I found this name somewhere, and I like it.

On http://aabs.wordpress.com the Intend is defined like this:

Intent: Provide a place to store scope or context related information or functionality that automatically follows the flow of execution between execution scopes or domains.

Read more about the pattern here: http://aabs.wordpress.com/2007/12/31/the-ambient-context-design-pattern-in-net/

.NET uses often as for example in System.Transactions.TransactionScope or System.Web.HttpContext.

While TransactionScope is saved per thread using [ThreadLocal], HttpContext is sometimes spans multiple threads following the flow of a full request execution – which can be asynchronous.

Example

The new Library System.Transactions offers generic transaction handling to your Application. Every method called within that scope can now join the running transaction, so does Ado.NET.

using(var t = new TransactionScope())
{
  // do something with for example ADO.Net
  t.Complete();
}

Why do they use the using-statement here?

LocalDataStoreSlot and [ThreadStatic]-Attribute

In many cases we just want to let the context be known within specific execution scope within one thread.

In .NET Framework 1.1 you had to use the LocalDataStoreSlot to store Data on a running Thread.

LocalDataStoreSlot slot = Thread.AllocateDataSlot();
Thread.SetData(slot, "my value");
string x = (string)Thread.GetData(slot);

In v2.0 Microsoft added the [ThreadStatic] attribute. Utilizing this class a static field can be turned into a thread static field, which holds the value just in the thread it was set in.

[ThreadStatic]
private static string myContext;

public void DoSomething()
{
  myContext = "value";
  DoSomethingElse();
  /* if DoSomethingElse() would be
   * called by another thread now
   * the current value would be null. */
  myContext = null;
}

public void DoSomethingElse()
{
  Console.WriteLine("Current value: " + myContext);
}

The Problem

If you don’t clean up, your bits may stay in the thread “forever”, even if it goes back to the thread pool! The next enqueued work item will find it there. Even worse in asp.net, where data could suddenly be shared between different requests using the same thread.

With a try..finally or making a helper class that implements IDisposable and cleans up on Dispose you can avoid these problems.

If you have nested scopes, the outer scope should be recovered, after the inner one has been closed, right?

The Solution

I created a class named ThreadVariable<T> which behaves pretty much like a static field marked as a [ThreadStatic]. But instead of assigning a value directly, a value is always only valid within a specific scope.

public static readonly ThreadVariable<string>
       myContext = new ThreadVariable<string>();

public void DoSomething()
{
  using(myContext.Use("value"))
  {
    DoSomethingElse();
    /* if DoSomethingElse() would be
     * called by another thread now
     * the current value would be empty. */
  }
  // the value is not available anymore
}

public void DoSomethingElse()
{
  Console.WriteLine("Current value: " + myContext.Value);
}

 

Grab the bits and feel free to copy what you need:
ThreadVariable Source and Tests (VS 2008) (Zip, 40k)
Update: Is now available as Minimod from Nuget or Github.

Features:

  • Allows nested scopes. Protects from messing up the values by disposing scopes wrongly.
  • The Property Current will throw an InvalidOperationException if you try to access it from the outside of a scope. This helps preventing NullReferenceExeptions
  • CurrentOrDefault will return the value within the current scope, or if it isn’t available, default(T).
    This is nice, if you want to use the coalescing operator ??:
    (for example: return threadVar.CurrentOrDefault ?? “another value”;)
  • In the constructor you can pass a fallback value. This will then always be returned on Current and on CurrentOrDefault, even if no value is available in the calling context.
  • HasCurrent indicates wether there is a value available. Note: is always true, if a fallback value is present.

More Examples

Continue reading

Using the using-statement

“Using statement?”, you may ask. “What is so interesting about that? I use it every day importing tons of namespaces!”

Well, i mean the other using statement; that one that results in a nice try..finally in IL, without having to write lots of code.

Well lets say you want to access a file, a database, or whatever resource that needs to be closed after usage:

StreamReader sr = new StreamReader(@"c:\mytextfile.txt");
sr.ReadToEnd().Count(); // just doing something
sr.Close(); // closing a resource explicitly. gooood!
The problem here is: If the file for example is not encoded correctly, or you’re just doing something inbetween opening and closing your reader that might fail, you’re resource will not be closed until the GC disposes it. This in some cases might mean, until your application is closed.
Putting a try catch arround it helps:
StreamReader sr = null;
try
{
  sr = new StreamReader(@"c:\mytextfile.txt");
  sr.ReadToEnd().Count(); // just doing something
}
finally
{
  if (sr != null) // StreamReader.ctr() could fail...
  sr.Close();
}

The using statement does exactly the same. The IL-Code also looks pretty similar, but it is way easier to write.

using(StreamReader sr = new StreamReader(@"c:\my.txt"))
{
  sr.ReadToEnd().Count(); // just doing something
}
The using-statement takes any object implementing IDisposable. In the end or in case of any error, it will safely dispose the used resource. The Dispose()-Method on Streams or any other Reader/Writer in usually does the same thing as Close() does.
You can even nest them if you have to use multiple resource at once:
using(StreamReader sr1 = new StreamReader(@"c:\my1.txt"))
using (StreamReader sr2 = new StreamReader(@"c:\my2.txt"))
using (StreamWriter sw = new StreamWriter(@"c:\mynew.txt"))
{
  sw.WriteLine(sr1.ReadToEnd());
  sw.WriteLine(sr2.ReadToEnd());
}

Almost any resource usage in .Net, for example ADO.Net implements the IDisposable on their classes. The connection will be closed and disposed, the transaction will be rolled back if something fails before commit.

using (var conn = new SqlConnection("..."))
{
  using (var st = conn.BeginTransaction())  
  {
    conn.Open();
  var sc = conn.CreateCommand();
    sc.CommandText = "UPDATE ...";
    sc.ExecuteNonQuery();
  var sc2 = conn.CreateCommand();
    sc2.CommandText = "SELECT ...";
    using (var reader = sc2.ExecuteReader())
  {
  return reader.GetString(0);
  }
  st.Commit();
  }
}

Have fun!

Note:There is no guarantee, that IDisposable.Dispose() on classes you find in .NET or other libraries will close everything as necessary. On the WCF clients, for instance, you need to call Abort() instead of Close() or Dispose() in case of an communication error, otherwise your connection will stay opened.

If you’re in doubt on a certain class, just use Reflector to check its behaviour.

Updated: Other Resources

kick it on DotNetKicks.com