Signum Framework Logo
"Open framework that encourages convention over configuration, using C# code,
not XML files, to model at the right level of abstraction and achieve deadlines.
...but also has a full Linq provider, and syncs the schema for you!"



Source code




This class contains three handy static methods to retrieve the information you usually put in your application 'About ...' window:

Nice Windows Version

Returns the commercial name of the windows installed in the current machine (Windows 95, NT 4.0, XP, 2003 Server, Vista)

In the New version "Windows Vista" has been replaced by "Windows Vista / 2008 Server", and "Windows 7" has been added

public static string NiceWindowsVersion(this OperatingSystem os)


//Writes: Windows Vista


Returns the DateTime of the moment that an assembly was compiled.

public static DateTime CompilationTime(this Version v)

In order to enable this functionality, you have to use a * symbol in sour AssemblyVersionAttribute (AssemblyInfo.cs usually).

[assembly: AssemblyVersion("1.0.*")] 

Otherwise it will return 31/12/1999 (first they of the .Net religion? :P)


//Writes: 08/02/2009 18:20:36
//(yeah, I'm working on a Sunday)


Returns a list of all the .Net FrameworkVersions installed in the current machine in the shape of NetFrameworkVersion objects., by looking at the Registry.

The new version correctly detects the ancient .Net Framework 1.0 (it uses different Registry Keys)

public static List<NetFrameworkVersion> FrameworkVersions()

public class NetFrameworkVersion { public string GlobalVersion { get; } public string FullVersion { get; } public int? ServicePack { get; }

public override string ToString() { return GlobalVersion + (ServicePack != null ? " SP" + ServicePack : ""); } }


//Writes in my machine:
//v2.0.50727 SP2
//v3.0 SP2
//v3.5 SP1


This simple class implements IDispoable by executing an action taken as a parameter.

public class Disposable: IDisposable
    Action action;
    public Disposable(Action action)
        if (action == null)
            throw new ArgumentNullException("action");

this.action = action; }

public void Dispose() { if (action != null) action(); } }

Handy for simple patterns using using statement and lambdas, like this:

static IDisposable Time(string actionName)
    Console.WriteLine("Starting {0}", actionName); 
    Stopwatch sw = Stopwatch.StartNew();
    return new Disposable(() => 
       Console.WriteLine("{0} take {1}", actionName, sw.Elapsed);


using (Time("Siesta")) { Console.WriteLine("zzZzZZ"); Thread.Sleep(1000); } //Writes: //Starting Siesta //zzZzZZ //Siesta take 00:00:01.0010197


MyRandom class has some improvements over Random class.

It has a static property to access a ThreadStatic field, so you won't need to instantiate a Random class.

static Random random;

public static Random Current { get { return random ?? (random = new Random()); } }

Also, it provides some extension methods for Random class:

public static bool NextBool(this Random r)

public static char NextUppercase(this Random r) //ABCDEFGHJKLMNPQRSTWXYZ public static char NextLowercase(this Random r) //abcdefgijkmnopqrstwxyz public static char NextChar(this Random r) //randomly upper and lowercase

//Same but returning string of a given length public static string NextUppercaseString(this Random r, int length) public static string NextLowercaseString(this Random r, int length) public static string NextString(this Random r, int length)

//Returns a 32-bit int representing a color public static int NextAlphaColor(this Random r) public static int NextColor(this Random r) public static int NextColor(this Random r, int minR, int maxR, int minG, int maxG, int minB, int maxB)

//A random DateTime between min and max public static DateTime NextDateTime(this Random r, DateTime min, DateTime max)

public static long NextLong(this Random r, long max) public static long NextLong(this Random r, long min, long max)

//Picks randomly an element or the array public static T NextElement<T>(this Random r, params T[] elements)


MyRandom.Current.NextBool(); //False

MyRandom.Current.NextUppercase(); //E MyRandom.Current.NextChar(); //b MyRandom.Current.NextLowercaseString(5); //jmdym MyRandom.Current.NextString(5); //GWtWJ

MyRandom.Current.NextColor(); //-1193927 (just a number, but a color in soul) MyRandom.Current.NextDateTime(new DateTime(2000, 1, 1), new DateTime(2008, 1, 1)); MyRandom.Current.NextLong(1000000000); //262778249 MyRandom.Current.NextElement("eins", "zwai", "drei"); //drei


Small wrapper over Console for Threading scenarios.

Usually, on loading applications many threads are running at the same time, SafeConsole provides a centralized SyncKey to lock the console, and some methods that take this lock before writing in the Console.

public static class SafeConsole
   public static readonly object SyncKey = new object();

public static void WriteLine() public static void WriteLine(string format, params object[] parameters) public static void Write(string format, params object[] parameters)

//Changes the Console.ForegrounColor, writes the text, and restores the color as the same critical region public static void WriteLineColor(ConsoleColor color, string format, params object[] parameters)

//Writes the line and sets the cursor at the beginning of the line, to the next line overrides this one //Handy for static progress counters public static void WriteSameLine(string format, params object[] parameters) }


Simplifies binary serialization and deserialization of objects to files and byte[] for simple scenarios.

public static class Serialization
   public static byte[] ToBytes(object graph)
   public static void ToFile(object graph, string fileName)

public static object FromBytes(byte[] array) public static object FromFile(string fileName) }


An implementation of Levenshtein string distance. Result the number of editions (insertion, substitution and removal) necessary to convert one string to the other.

Used to know how similar, or different, two small strings are. The space it takes is proportional to the product of the lengths of the strings don't use it for big documents.

public class StringDistance
    //returns the number of editions necessary to transform s into t.
    public int Distance(string s, string t);

Internally it holds a potentially big bi-dimensional array. When used to find the distance of many strings it's better to use the same object instance.


StringDistance sd = new StringDistance();
sd.Distance("Hello", "Hola"); //3
sd.Distance("Hello", "Holla"); //2
sd.Distance("Hello", "Holle"); //2
sd.Distance("Hello", "Helle"); //1
sd.Distance("Hello", "Hello"); //0


Switch<T> and Switch<T,R> try to enrich C# switch statement. The idea comes from Bart De Smet's Blog, and adds the following features:

  • Uses complex objects for matching by calling Equal (not just numbers, enums and string)
  • Uses predicates for matching
  • Uses types for matching

This is Switch<T>:

public class Switch<T>
   //Creates a new Switch object that will try to match 'value' (Switch can not be 'reused') 
   public Switch(T value)
   //Adds a new case, using value to match, and if so executing action 
   //and stopping evaluation. Returns itself for chaining. 
   public Switch<T> Case(T value, Action<T> action)
   //Uses condition for matching, if so executes action 
   //and stopping evaluation. Returns itself for chaining. 
   public Switch<T> Case(Predicate<T> condition, Action<T> action)

//Uses type S to to match, if so executes action //and stopping evaluation. Returns itself for chaining. public Switch<T> Case<S>(Action<S> action) where S: T

//Executes action with no condition. public void Default(Action<T> action) }


new Switch<object>(3)
  .Case("hello", o => Console.WriteLine("Hello!"))
  .Case(o => o.ToString() == "hi", o => Console.WriteLine("It's "))
  .Case<int>(i => Console.WriteLine(i*2));
//Writes: 6 

This exotic Switch construct is less efficient than a standard switch statement. We expect Switch to be seen as a clever idea by some people, and as an eccentricity by others. Use it if it simplifies your code and not in performance-critical scenarios.

Switch<T,R> class, on the other side, behaves like an expression, so it returns a value:

public class Switch<T,R>
   //Creates a new Switch object that will try to match 'value' (Switch can not be 'reused') 
   public Switch(T value)
   //Adds a new case, using value to match, and if so taking 'result' as the result
   //and stopping evaluation. Returns itself for chaining. 
   public Switch<T, R> Case(T value, R result)
   public Switch<T,R> Case(T value, Func<T,R> func) //same but taking func(value) as the result

//Adds a new case, using predicate to match, and if so taking 'result' as the result //and stopping evaluation. Returns itself for chaining. public Switch<T, R> Case(Predicate<T> condition, R result) public Switch<T, R> Case(Predicate<T> condition, Func<T, R> func) //same but taking func(value) as the result

//Adds a new case, using type S to match, and if so taking 'result' as the result //and stopping evaluation. Returns itself for chaining. public Switch<T, R> Case<S>(R result) where S : T public Switch<T, R> Case<S>(Func<S, R> func) where S : T //same but taking func((S)value) as the result

//If no Case has match so far uses 'result' as the result. Finally returns result public R Default(R result) public R Default(Func<T, R> func) //same but taking func(value) as the result //If no case has match throws InvalidOperationException, otherwise returns result public R NoDefault() public R NoDefault(string message) //same but a custom message on the InvalidOperationException }


int length = new Switch<object, int>("hello")
               .Case(o => o == null, 0)
               .Case<string>(s => s.Length)
               .Default(o => o.ToString().Length);

Console.WriteLine(length); //Writes: 5


In the same way throwing an Exception is an agnostic way of communicating errors, so you can throw an exception from 'pure' logic assembly and it can be cached and displayed in different ways in a ASP.Net, WinForms or WPF application, ProgressProxy class tries to make a agnostic way of communicating progress (to the user interface, presumably).

ProgressProxy allows both a numerical (min, max, position, for a ProgressBar usually) way of indicating progress and a textual one ("Removing C:\Windows folder", "Fixing Registry Mess",...)

public class ProgressProxy
    //Event that notifies to the user interface about progress changes
    public event EventHandler<ProgressArgs> Changed;
    //Values for a ProgressBar
    public int Min {get;}
    public int Max {get;}    
    public int Position {get; set;} //-1 if no numeric progress enabled
    //Textural representation of the current task
    public string CurrentTask {get; set;}
    //Methods to initiate a new task
    public void Start(int numTasks)
    public void Start(string currentTask)
    public void Start(int max, string currentTask)
    public void Start(int min, int max, string currentTask)

//Sets currentTask and nicrements position 1 (otherwise use CurrentTask property setter) public void NextTask(string currentTask) //Sets position and currentTask throwing just one event public void NextTask(int position, string currentTask)

public void Reset() }

public class ProgressArgs : EventArgs { public readonly ProgressAction Action; public ProgressArgs(ProgressAction a) }

public enum ProgressAction { Interval = 1, //When Min and Max has changed Position = 2, //When Position have changed Task = 4, //When current task have changed }


//Pure logic code
private static void Sleep(ProgressProxy pp)
    pp.Start("Getting Into bed"); 
    pp.Start(10, "Counting sheeps");
    for (int i = 0; i < 10; i++)
        pp.Position = i;
    pp.Start(3); //Dreams
    pp.NextTask("Dream 1: Donuts");
    pp.NextTask("Dream 2: Beeer...");
    pp.NextTask("Dream 3: Nuclear Plant failure!!!");


//Called from a Console Application ProgressProxy pp = new ProgressProxy(); pp.Changed += (sender, pa) => { if ((pa.Action & ProgressAction.Task) != 0) Console.WriteLine("{0}", pp.CurrentTask);

if (pp.Position != -1 ) { int progress = (10 * (pp.Position - pp.Min)) / (pp.Max - pp.Min); string str = ".".Replicate(progress).PadRight(10); Console.WriteLine("[{0}] ", str); } };

Sleep(pp); //Writes: //Getting Into bed //Counting sheep //[ ] //[ ] //[.. ] //[.... ] //[...... ] //[........ ] // //[ ] //Dream 1: Donuts //[... ] //Dream 2: Beeer... //[...... ] //Dream 3: Nuclear Plant failure!!! //[..........] // //[ ] //


Finally, when a ProgressEnumerator is 'inserted' between a IEnumerable producer and a consumer, it produces some statistics like percentage of completion, elapsed and remaining time, and estimated finish time. Handy in loading applications.

ProgressEnumerator is not meant to be instantiated manually, but instead call EnumerableExtensions's ToProgressEnumerator.

public static IEnumerable<T> ToProgressEnumerator<T>(this IEnumerable<T> source, out IProgressInfo pi)

public interface IProgressInfo { double Percentage { get; } double Ratio { get; } TimeSpan Elapsed { get; } TimeSpan Remaining { get; } DateTime EstimatedFinish { get; } //Also, it has a nice ToString() }


IProgressInfo pi;
0.To(20).ToProgressEnumerator(out pi).ForEach(num =>
//5,00% | 0h 00m 00s -> 09/02/2009 09:07:36
//10,00% | 0h 00m 01s -> 09/02/2009 09:07:38
//15,00% | 0h 00m 02s -> 09/02/2009 09:07:39
//20,00% | 0h 00m 02s -> 09/02/2009 09:07:39
//25,00% | 0h 00m 02s -> 09/02/2009 09:07:39
//30,00% | 0h 00m 02s -> 09/02/2009 09:07:39
//35,00% | 0h 00m 02s -> 09/02/2009 09:07:40
//40,00% | 0h 00m 02s -> 09/02/2009 09:07:40
//45,00% | 0h 00m 01s -> 09/02/2009 09:07:40
//50,00% | 0h 00m 01s -> 09/02/2009 09:07:40
//55,00% | 0h 00m 01s -> 09/02/2009 09:07:40
//60,00% | 0h 00m 01s -> 09/02/2009 09:07:40
//65,00% | 0h 00m 01s -> 09/02/2009 09:07:40
//70,00% | 0h 00m 01s -> 09/02/2009 09:07:40
//75,00% | 0h 00m 00s -> 09/02/2009 09:07:40
//80,00% | 0h 00m 00s -> 09/02/2009 09:07:40
//85,00% | 0h 00m 00s -> 09/02/2009 09:07:40
//90,00% | 0h 00m 00s -> 09/02/2009 09:07:40
//95,00% | 0h 00m 00s -> 09/02/2009 09:07:40
//100,00% | 0h 00m 00s -> 09/02/2009 09:07:40

Or even better, using SafeConsole.WriteSameLine to use the same as always.

IProgressInfo pi;
0.To(20).ToProgressEnumerator(out pi).ForEach(num =>


This simple class implements a TextWriter that writes using System.Diagnostics.Debug class. Useful for tests.


public void Initialize()
   Connection.CurrentLog = new DebugTextWriter();


Since this class is not used very often, the methods are not extension method any more to avoid clutter. This class has also been renamed from TreeExtensions to TreeHelper.


Given a tree where the child has a reference to the parents, returns a tree of Node<T> relating each parent to their children.

public static List<Node<T>> ToTreeC<T>(IEnumerable<T> collection, Func<T, T> getParent) where T: class 
public static List<Node<T>> ToTreeS<T>(IEnumerable<T> collection, Func<T, T?> getParent) where T : struct

public class Node<T> { public T Value { get; set; } public List<Node<T>> Childs { get; set; }

public Node(){...} public Node(T value){...} }


List<Node<int>> roots = new[] { 5,6,7,8,9 }.ToTreeS(a => (a / 2).DefaultToNull());
Node<int> parent = roots.Single();
//parent is a node like this: 
//Node 1
//  Node 2
//    Node 5
//    Node 4
//      Node 8
//      Node 9
//  Node 3
//    Node 6
//    Node 7

If you're curious, below is the function we used to write the text, it uses anonymous recursion, and many StringExtensions like Formato, Add, ToString and Ident:

Func<Node<int>, string> toStr = null;
toStr = node => "Node {0}".Formato(node.Value).Add(node.Childs.ToString(toStr, "\r\n").Indent(2), "\r\n");


Allows to explore in a BreathFirst fashion an object and all its' children recursively. Doesn't keep track of items so it won't work on a general graph, just trees. For a generall graph use DirectedGrap instead.

public static IEnumerable<T> BreathFirst<T>(T root, Func<T, IEnumerable<T>> childs)


Node<int> parent = .../ as defined in previous example: ToTree
parent.BreathFirst(a => a.Childs).ToString(a => a.Value.ToString(), ", "); 

//1, 3, 7, 6, 2, 4, 9, 8, 5

Creative Commons License Signum Framework Site by Signum Software is licensed under a Creative Commons Attribution 3.0 License.
Powered by ScrewTurn Wiki version