Showing posts with label Extension. Show all posts
Showing posts with label Extension. Show all posts

Thursday, December 21, 2017

WinForms TextBox Get as Double or Integer

I always end up returning to Windows Forms when I want to code some tool or prototype an idea. This time I just want to share two extension methods for retrieving the contents of a TextBox as an Integer or a Double.

public static double AsDouble(this TextBox textBox)
{
 var s = textBox.Text.Replace(",", ".").Trim();
 return double.TryParse(s, out var d) ? d : double.NaN;
}
public static int AsInt(this TextBox textBox)
{
 var s = textBox.Text.Trim();
 return int.TryParse(s, out var i) ? i : 0;
}

The colon to period replacement is to ensure that Swedish formatting works with the default parser. No guarantee that it will work with all cultures.


All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment, not required but appreciated! :)

Hope this helps someone out there!

Friday, October 13, 2017

System.Math extension methods

Why

Because I've lately started to think a little more functional, this also allows for nice chaining of calls to the Math class.

How to use

Say you want to calculate the angle between 2 vectors by taking arc cosine of our dot product to give us the angle:
With normal Math usage..
var dot = vector1.X* vector2.X + vector1.Y * vector2.Y + vector1.Z * vector2.Z;
double radians = Math.Acos(dot);
Same example with our extensions
var dot = vector1.X* vector2.X + vector1.Y * vector2.Y + vector1.Z * vector2.Z;
double radians = dot.Acos();

The above example but with a method to calculate the dot product.
double radians = vector1.Dot(vector2).Acos();


Code for your pleasure

public static class MathExtensions
{
    public static decimal Abs(this decimal d)
    {
        return Math.Abs(d);
    }
    public static float Abs(this float d)
    {
        return Math.Abs(d);
    }
    public static double Abs(this double d)
    {
        return Math.Abs(d);
    }
    public static int Abs(this int d)
    {
        return Math.Abs(d);
    }
    public static long Abs(this long d)
    {
        return Math.Abs(d);
    }
    public static short Abs(this short d)
    {
        return Math.Abs(d);
    }
    public static short Abs(this byte d)
    {
        return Math.Abs(d);
    }
    public static decimal Max(this decimal d, decimal x)
    {
        return Math.Max(d, x);
    }
    public static float Max(this float d, float x)
    {
        return Math.Max(d, x);
    }
    public static double Max(this double d, double x)
    {
        return Math.Max(d, x);
    }
    public static int Max(this int d, int x)
    {
        return Math.Max(d, x);
    }
    public static long Max(this long d, long x)
    {
        return Math.Max(d, x);
    }
    public static short Max(this short d, short x)
    {
        return Math.Max(d, x);
    }
    public static short Max(this byte d, byte x)
    {
        return Math.Max(d, x);
    }
    public static decimal Min(this decimal d, decimal x)
    {
        return Math.Min(d, x);
    }
    public static float Min(this float d, float x)
    {
        return Math.Min(d, x);
    }
    public static double Min(this double d, double x)
    {
        return Math.Min(d, x);
    }
    public static int Min(this int d, int x)
    {
        return Math.Min(d, x);
    }
    public static long Min(this long d, long x)
    {
        return Math.Min(d, x);
    }
    public static short Min(this short d, short x)
    {
        return Math.Min(d, x);
    }
    public static short Min(this byte d, byte x)
    {
        return Math.Min(d, x);
    }

    public static int Sign(this decimal d)
    {
        return Math.Sign(d);
    }
    public static int Sign(this float d)
    {
        return Math.Sign(d);
    }
    public static int Sign(this double d)
    {
        return Math.Sign(d);
    }
    public static int Sign(this int d)
    {
        return Math.Sign(d);
    }
    public static int Sign(this long d)
    {
        return Math.Sign(d);
    }
    public static int Sign(this short d)
    {
        return Math.Sign(d);
    }
    public static int Sign(this byte d)
    {
        return Math.Sign(d);
    }
    public static decimal Floor(this decimal d)
    {
        return Math.Floor(d);
    }
    public static double Floor(this float d)
    {
        return Math.Floor(d);
    }
    public static double Floor(this double d)
    {
        return Math.Floor(d);
    }
    public static decimal Round(this decimal d)
    {
        return Math.Round(d);
    }
    public static decimal Round(this decimal d, int x)
    {
        return Math.Round(d, x);
    }
    public static decimal Round(this decimal d, int x, MidpointRounding mr)
    {
        return Math.Round(d, x, mr);
    }
    public static decimal Round(this decimal d, MidpointRounding mr)
    {
        return Math.Round(d, mr);
    }
    public static double Round(this float d)
    {
        return Math.Round(d);
    }
    public static double Round(this double d)
    {
        return Math.Round(d);
    }
    public static double Round(this double d, int x)
    {
        return Math.Round(d, x);
    }
    public static double Round(this double d, int x, MidpointRounding mr)
    {
        return Math.Round(d, x, mr);
    }
    public static double Round(this double d, MidpointRounding mr)
    {
        return Math.Round(d, mr);
    }
    public static decimal Ceiling(this decimal d)
    {
        return Math.Ceiling(d);
    }
    public static double Ceiling(this float d)
    {
        return Math.Ceiling(d);
    }
    public static double Ceiling(this double d)
    {
        return Math.Ceiling(d);
    }
    public static double Acos(this double d)
    {
        return Math.Acos(d);
    }
    public static double Asin(this double d)
    {
        return Math.Asin(d);
    }
    public static double Atan(this double d)
    {
        return Math.Atan(d);
    }
    public static double Atan2(this double d, double x)
    {
        return Math.Atan2(d, x);
    }
    public static double Cos(this double d)
    {
        return Math.Cos(d);
    }
    public static double Cosh(this double d)
    {
        return Math.Cosh(d);
    }
    public static double Exp(this double d)
    {
        return Math.Exp(d);
    }
    public static double Sin(this double d)
    {
        return Math.Sin(d);
    }
    public static double Sinh(this double d)
    {
        return Math.Sinh(d);
    }
    public static double Tan(this double d)
    {
        return Math.Tan(d);
    }
    public static double Tanh(this double d)
    {
        return Math.Tanh(d);
    }
    public static long BigMul(this int a, int b)
    {
        return Math.BigMul(a, b);
    }
    public static double IEEERemainder(this double d, double y)
    {
        return Math.IEEERemainder(d, y);
    }
    public static double Log(this double d)
    {
        return Math.Log(d);
    }
    public static double Log(this double d, double x)
    {
        return Math.Log(d, x);
    }
    public static double Log10(this double d)
    {
        return Math.Log10(d);
    }
    public static double Sqrt(this double d)
    {
        return Math.Sqrt(d);
    }
    public static decimal Truncate(this decimal d)
    {
        return Math.Truncate(d);
    }
    public static double Truncate(this double d)
    {
        return Math.Truncate(d);
    }
    public static double Pow(this double d, double power)
    {
        return Math.Pow(d, power);
    }
}

Quite a lot of overloads, I think I got them all but if you find that I've missed one, please comment on this post and I will add it!

All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment, not required but appreciated! :)

Hope this helps someone out there!


Thursday, December 29, 2016

Performance: Enum ToString or GetName


Usually I am too lazy to bother using anything else than the ordinary ToString when working with enums, but I always have that filthy feeling that I am cheating.
If there is a dedicated method in the framework to do something, there probably is a reason for it. And knowing that the Enum class contains a GetName method to get the string representation of a enum value made me want to know if there is a performance difference between the two.

First, the tested Enum.GetName method, for sake of argument wrapped up as an Extension for easier and cleaner usage.

public static class Extension
{
    public static string GetEnumName<T>(this T t) where T : struct, IConvertible
    {
        return Enum.GetName(typeof (T), t);
    }
}

Back to extensions list

The test rigg

The test rigg is basically the same that I used in Performance of different lock methods in .net.
Uses RunningAverage to calculate the average without storing each individual number.
Just cleaned up and simplified for this scenario:

Data

private enum SmallEnum
{
    Small,
    Larger
}
private enum LargerEnum
{
    a, b, c, d, e, f, g, h,
    aaaaa, bbbbb, ccccc, ddddd,
    xxxxx, yyyyy, zzzzz,
    VeryLongNameThisIs,
    OtherName, Test, oooo, olf,
    eowind, eeeee, ss, qqqqq,
    mu, miu, bach, escher,
    godel, code, number, last
}

Decided to test 2 different enums with different number of elements to see if that has any impact. The small has 2 elements and the larger has 32.

Code

private void ExecuteTestSmall(int iterations)
{
    var type = "small";
    string s = string.Empty;
    try
    {
        var testData = GenerateTestDataSmall();
        var toStringTimings = new RunningAverage();
        var getNameTimings = new RunningAverage();
        for (int i = 0; i < iterations; i++)
        {
            for (int dataIndex = 0; dataIndex < testData.Count; dataIndex++)
            {
                var item = testData[dataIndex];
                toStringTimings.Add(TimeAction(() =>
                {
                    s = item.ToString();
                }));
                if (!string.IsNullOrEmpty(s))
                    s = string.Empty;
                getNameTimings.Add(TimeAction(() =>
                {
                    s = item.GetEnumName();
                }));
                if (!string.IsNullOrEmpty(s))
                    s = string.Empty;
            }
        }
        Log($"{type}ToString\tDataCount\t2\tIterations:\t{iterations}\tAverage:\t{toStringTimings.Average:0.000}\tticks");
        Log($"{type}GetName\tDataCount\t2\tIterations:\t{iterations}\tAverage:\t{getNameTimings.Average:0.000}\tticks");
    }
    catch (Exception ex)
    {
        Log($"{type}Fail\tDataCount\t2\tIterations:\t{iterations}\tFailed\t{ex.Message}");
    }
}

Ok, I was lazy. I created 2 methods instead of putting the effort to reuse it. The above is for the SmallEnum. Exactly the same code for the LargerEnum tester with difference in GenerateTestDataSmall to return a List<LargerEnum> instead of List<SmallEnum>.

This was executed as follows:
public void Execute()
{
 Log("--------------------------------------");
 Log("... single thread");
 ExecuteTestSmall(250000);
 ExecuteTestLarger(250000);
}

250000 times each.

Results

ToString enum size 2 Iterations: 250000 Average: 1.231 ticks
GetName enum size 2 Iterations: 250000 Average: 0.662 ticks
ToString enum size 32 Iterations: 250000 Average: 1.357 ticks
GetName enum size 32 Iterations: 250000 Average: 0.692 ticks

Conclusion

Using the dedicated Enum.GetName function to get the string representation instead of the lazy object.ToString() seems to be twice faster. But in the end, we are talking around 1 tick, so maybe not the first place to start optimizing if you have a performance issue in you application. As I wrote above, it just feels a little bit lazy to not do it the correct way ;)

All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Hope this helps someone out there :)



Friday, November 11, 2016

PictureBox SafeReplaceImage extension


Another extension for the winforms picturebox component.
Basically it just lets you forget about the disposal of the previous image. Saved me a lot of headache.

Some source-code (C#)
public static void SafeReplaceImage(this PictureBox pbox, Image image)
{
 var tmp = pbox.Image;
 pbox.Image = image;
 if (tmp != null)
 {
  tmp.Dispose();
  tmp = null;
 }
}

Hope this helps someone out there! :)

Back to extensions list


Monday, November 7, 2016

Extension PictureBox ResizeImageToFit


Another useful extension, this time for the standard Windows Forms PictureBox. The issue for me, is that I usually just want to throw a picture at it and it should just show it, not crop it, not kill the aspect ratio etc. So I tend to use this extension method after assigning a new picture to the PictureBox.Image property to correctly show the picture in center mode if it is smaller then the box, or zoom it to fit inside the box if it is larger, still keeping the aspect ratio.

Some source-code (C#)
public static void ResizeImageToFit(this PictureBox pbox)
{
 if (pbox.Size.Height > pbox.Image.Size.Height && pbox.Size.Width > pbox.Image.Size.Width)
  pbox.SizeMode = PictureBoxSizeMode.CenterImage;
 else
  pbox.SizeMode = PictureBoxSizeMode.Zoom;
}

Hope this helps someone out there :)

Back to extensions list


Friday, November 4, 2016

String extension for Contains, with StringComparison

So, many of the built in string methods have the possibility to set the StringComparison in code, to for example OrdinalIgnoreCase wich is my favorite for most back-end processing.
Sad thing is, the Contains does not have it. So here is a small extension that fixes it with the help of IndexOf method

Some source-code (C#) to copy into your utilities class.

public static bool Contains(this string s, string sub, StringComparison comparison)
{
    return s.IndexOf(sub, comparison) != -1;
}

Hope this helps someone out there :)

Back to extensions list

Saturday, October 8, 2016

WinForms RichTextBox Append Log and UIThread extensions

Turn any RichTextBox in winforms to a log view. Just call rtxt.AppendLog("someString"); and it will append that to a new line in the richtextbox. And scroll it to view.

public static void AppendLog(this RichTextBox rtxt, string s)
{
 rtxt.UIThread(() =>
 {
  rtxt.AppendText($"{s}{Environment.NewLine}");
  rtxt.SelectionLength = 0;
  if (rtxt.Lines.Length > 10000)
  {
   rtxt.Lines = rtxt.Lines.Skip(5000).ToArray();
  }
  rtxt.SelectionStart = rtxt.TextLength;
  rtxt.ScrollToCaret();
 });
}
The above snippet of code requires the following to function correctly.
static public void UIThread(this Control control, Action code)
{
 if (control.InvokeRequired)
 {
  control.BeginInvoke(code);
  return;
 }
 code.Invoke();
}
I can't take credit, found it years ago on some forum somewhere. But here it is anyway. It makes a call to a winforms control synschronize with the GUI thread so that no cross-threading exceptions is thrown. GUI items can only be modified from the GUI thread and this ensures just that.

The exception thrown if correct thread synchronization is not used is: 
System.InvalidOperationException was unhandled
  HResult=-2146233079
  Message=Cross-thread operation not valid: Control 'rtxtOutput' accessed from a thread other than the thread it was created on.
  Source=System.Windows.Forms
  StackTrace:
       at System.Windows.Forms.Control.get_Handle()
       at System.Windows.Forms.TextBoxBase.GetSelectionStartAndLength(Int32& start, Int32& length)
       at System.Windows.Forms.TextBoxBase.set_SelectionLength(Int32 value)
       at System.Windows.Forms.RichTextBox.set_SelectionLength(Int32 value)
       at ave.dev.winform.Form1.ticker_Tick(Object sender, EventArgs e) in C:\tfs\YYY\Form1.cs:line 54
       at ave.dev.winform.Form1._loggerHook_NewLogLine(String s) in C:\tfs\YYY\Form1.cs:line 38


Back to extensions list

Saturday, October 1, 2016

Get random item from a list extension


private static Random _random = new Random();
public static T GetRandom<T>(this List<T> list)
{
    if (list.Count == 0)
        return default(T);
    if (list.Count == 1)
        return list[0];
    return list[_random.Next(0, list.Count)];
}

Very useful in a broad range of scenarios when you want to get a random element from a list.
Just call myList.GetRandom()

Back to extensions list