AboutTools
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)
Example:
Console.WriteLine(Environment.OSVersion.NiceWindowsVersion());
CompilationTime
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)
Example:
Console.WriteLine(Assembly.GetEntryAssembly().GetName().Version.CompilationTime());
FrameworkVersions
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 : "");
}
}
Example:
AboutTools.FrameworkVersions().ToConsole();
Disposable
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(() =>
{
sw.Stop();
Console.WriteLine("{0} take {1}", actionName, sw.Elapsed);
});
}
(..)
using (Time("Siesta"))
{
Console.WriteLine("zzZzZZ");
Thread.Sleep(1000);
}
MyRandom¶
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.
[ThreadStatic]
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)
public static char NextLowercase(this Random r)
public static char NextChar(this Random r)
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)
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)
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)
public static T NextElement<T>(this Random r, params T[] elements)
Example:
MyRandom.Current.NextBool();
MyRandom.Current.NextUppercase();
MyRandom.Current.NextChar();
MyRandom.Current.NextLowercaseString(5);
MyRandom.Current.NextString(5);
MyRandom.Current.NextColor();
MyRandom.Current.NextDateTime(new DateTime(2000, 1, 1), new DateTime(2008, 1, 1));
MyRandom.Current.NextLong(1000000000);
MyRandom.Current.NextElement("eins", "zwai", "drei");
SafeConsole
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)
public static void WriteLineColor(ConsoleColor color, string format, params object[] parameters)
public static void WriteSameLine(string format, params object[] parameters)
}
Serialization
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)
}
StringDistance
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
{
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.
Example:
StringDistance sd = new StringDistance();
sd.Distance("Hello", "Hola");
sd.Distance("Hello", "Holla");
sd.Distance("Hello", "Holle");
sd.Distance("Hello", "Helle");
sd.Distance("Hello", "Hello");
Switch
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>:
[DebuggerStepThrough]
public class Switch<T>
{
public Switch(T value)
public Switch<T> Case(T value, Action<T> action)
public Switch<T> Case(Predicate<T> condition, Action<T> action)
public Switch<T> Case<S>(Action<S> action) where S: T
public void Default(Action<T> action)
}
Example:
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));
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:
[DebuggerStepThrough]
public class Switch<T,R>
{
public Switch(T value)
public Switch<T, R> Case(T value, R result)
public Switch<T,R> Case(T value, Func<T,R> func)
public Switch<T, R> Case(Predicate<T> condition, R result)
public Switch<T, R> Case(Predicate<T> condition, Func<T, R> func)
public Switch<T, R> Case<S>(R result) where S : T
public Switch<T, R> Case<S>(Func<S, R> func) where S : T
public R Default(R result)
public R Default(Func<T, R> func)
public R NoDefault()
public R NoDefault(string message)
}
Example:
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);
ProgressProxy
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
{
public event EventHandler<ProgressArgs> Changed;
public int Min {get;}
public int Max {get;}
public int Position {get; set;}
public string CurrentTask {get; set;}
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)
public void NextTask(string currentTask)
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,
Position = 2,
Task = 4,
}
Example:
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;
Thread.Sleep(100);
}
pp.Start(3);
pp.NextTask("Dream 1: Donuts");
pp.NextTask("Dream 2: Beeer...");
pp.NextTask("Dream 3: Nuclear Plant failure!!!");
pp.Reset();
}
(...)
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);
ProgressEnumerator
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; }
}
Example:
IProgressInfo pi;
0.To(20).ToProgressEnumerator(out pi).ForEach(num =>
{
Console.WriteLine(pi.ToString());
Thread.Sleep(100);
});
Or even better, using SafeConsole.WriteSameLine to use the same as always.
IProgressInfo pi;
0.To(20).ToProgressEnumerator(out pi).ForEach(num =>
{
SafeConsole.WriteSameLine(pi.ToString());
Thread.Sleep(100);
});
DebugTextWriter
This simple class implements a TextWriter that writes using System.Diagnostics.Debug class. Useful for tests.
Example:
[TestInitialize]
public void Initialize()
{
Connection.CurrentLog = new DebugTextWriter();
}
TreeHelper
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.
ToTree
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){...}
}
Example:
List<Node<int>> roots = new[] { 5,6,7,8,9 }.ToTreeS(a => (a / 2).DefaultToNull());
Node<int> parent = roots.Single();
Func<Node<int>, string> toStr = null;
toStr = node => "Node {0}".Formato(node.Value).Add(node.Childs.ToString(toStr, "\r\n").Indent(2), "\r\n");
Console.WriteLine(toStr(parent));
BreathFirst
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)
Example:
Node<int> parent = .../ as defined in previous example: ToTree
parent.BreathFirst(a => a.Childs).ToString(a => a.Value.ToString(), ", ");