"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!"
Search
Back
History
Other Utilities
[anchor|#AboutTools] == 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) {s:SF2| In the New version "Windows Vista" has been replaced by "Windows Vista / 2008 Server", and "Windows 7" has been added} <code lang="cs"> public static string NiceWindowsVersion(this ¬OperatingSystem os) </code> Example: <code lang="cs"> ¬Console.WriteLine(¬Environment.OSVersion.NiceWindowsVersion()); //Writes: Windows Vista </code> === CompilationTime === Returns the DateTime of the moment that an assembly was compiled. <code lang="cs"> public static ¬DateTime CompilationTime(this ¬Version v) </code> In order to enable this functionality, you have to use a * symbol in sour AssemblyVersionAttribute (AssemblyInfo.cs usually). <code lang="cs"> [assembly: ¬AssemblyVersion("1.0.*")] </code> Otherwise it will return 31/12/1999 (first they of the .Net religion? :P) Example: <code lang="cs"> ¬Console.WriteLine(¬Assembly.GetEntryAssembly().GetName().Version.CompilationTime()); //Writes: 08/02/2009 18:20:36 //(yeah, I'm working on a Sunday) </code> === 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. {s:SF2| The new version correctly detects the ancient .Net Framework 1.0 (it uses different Registry Keys)} <code lang="cs"> 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 : ""); } } </code> Example: <code lang="cs"> AboutTools.FrameworkVersions().ToConsole(); //Writes in my machine: //v2.0.50727 SP2 //v3.0 SP2 //v3.5 SP1 </code> [anchor|#Disposable] ==Disposable== This simple class implements IDispoable by executing an action taken as a parameter. <code lang="cs"> 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(); } } </code> Handy for simple patterns using [http://msdn.microsoft.com/en-us/library/yh598w02.aspx|using statement] and lambdas, like this: <code lang="cs"> 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); } //Writes: //Starting Siesta //zzZzZZ //Siesta take 00:00:01.0010197 </code> [anchor|#MyRandom] ==MyRandom== MyRandom class has some improvements over [http://msdn.microsoft.com/en-us/library/system.random.aspx|Random class]. It has a static property to access a ThreadStatic field, so you won't need to instantiate a Random class. <code lang="cs"> [¬ThreadStatic] static ¬Random random; public static ¬Random Current { get { return random ?? (random = new ¬Random()); } } </code> Also, it provides some extension methods for Random class: <code lang="cs"> 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) </code> Example: <code lang="cs"> ¬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 </code> [anchor|#SafeConsole] ==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. <code lang="cs"> 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) } </code> [anchor|#Serialization] ==Serialization== Simplifies binary serialization and deserialization of objects to files and byte<nowiki>[]</nowiki> for simple scenarios. <code lang="cs"> 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) } </code> [anchor|#StringDistance] ==StringDistance== An implementation of [http://en.wikipedia.org/wiki/Levenshtein_distance|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__. <code lang="cs"> public class StringDistance { //returns the number of editions necessary to transform s into t. public int Distance(string s, string t); } </code> {s:Note| 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: <code lang="cs"> ¬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 </code> [anchor|#Switch] ==Switch== <esc>Switch<T> and Switch<T,R></esc> try to enrich [http://msdn.microsoft.com/en-us/library/06tc147t(VS.71).aspx|C# switch statement]. The idea comes from [http://bartdesmet.net/blogs/bart/archive/2008/03/30/a-functional-c-type-switch.aspx|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 <esc>Switch<T></esc>: <code lang="cs"> [¬DebuggerStepThrough] 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) } </code> Example: <code lang="cs"> 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 </code> {s:Note| 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. } <esc>Switch<T,R></esc> class, on the other side, behaves like an expression, so it returns a value: <code lang="cs"> [¬DebuggerStepThrough] 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 } </code> Example: <code lang="cs"> 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 </code> [anchor|#ProgressProxy] == 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",...) <code lang="cs"> 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 } </code> Example: <code lang="cs"> //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; ¬Thread.Sleep(100); } pp.Start(3); //Dreams pp.NextTask("Dream 1: Donuts"); pp.NextTask("Dream 2: Beeer..."); pp.NextTask("Dream 3: Nuclear Plant failure!!!"); pp.Reset(); } (...) //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!!! //[..........] // //[ ] // </code> [anchor|#ProgressEnumerator] ==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. <code lang="cs"> 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() } </code> Example: <code lang="cs"> ¬IProgressInfo pi; 0.To(20).ToProgressEnumerator(out pi).ForEach(num => { ¬Console.WriteLine(pi.ToString()); ¬Thread.Sleep(100); }); //Writes: //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 </code> Or even better, using SafeConsole.WriteSameLine to use the same as always. <code lang="cs"> ¬IProgressInfo pi; 0.To(20).ToProgressEnumerator(out pi).ForEach(num => { ¬SafeConsole.WriteSameLine(pi.ToString()); ¬Thread.Sleep(100); }); </code> == DebugTextWriter == This simple class implements a TextWriter that writes using System.Diagnostics.Debug class. Useful for tests. Example: <code lang="cs"> [¬TestInitialize] public void Initialize() { ¬Connection.CurrentLog = new ¬DebugTextWriter(); } </code> == TreeHelper == {s:SF2| 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 <esc>Node<T></esc> relating each parent to their children. <code lang="cs"> 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){...} } </code> Example: <code lang="cs"> ¬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 </code> {s:Note| If you're curious, below is the function we used to write the text, it uses [http://blogs.msdn.com/wesdyer/archive/2007/02/02/anonymous-recursion-in-c.aspx|anonymous recursion], and many [StringExtensions] like Formato, Add, ToString and Ident:} <code lang="cs"> ¬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)); </code> === BreathFirst === Allows to explore in a [http://en.wikipedia.org/wiki/Breadth-first_search|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 [[DataStructures-Graphs|DirectedGraph] instead. <code lang="cs"> public static ¬IEnumerable<T> BreathFirst<T>(T root, ¬Func<T, ¬IEnumerable<T>> childs) </code> Example: <code lang="cs"> ¬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 </code>
Signum Framework Site by
Signum Software
is licensed under a
Creative Commons Attribution 3.0 License
.
Powered by
ScrewTurn Wiki
version 2.0.35.