TextBoxes for various number types Is there a way I could somehow have all this classes condensed into one, while keeping the code as clean as possible?

They are all doing essentially the same thing, just for the different number type. I don't know how to "generalize" TryParse() without using switch or if tree which doesn't seem very clean to me.

Base class:

public class TextBoxNum&lt;T&gt; : TextBox where T : IComparable&lt;T&gt;
{
    protected T min;
    protected T max;

    protected Value&lt;T&gt; value;

    public virtual void Update(object sender, EventArgs e)
    {

    }

    protected T Clamp(T input) 
    {
        if (input.CompareTo(max) &gt; 0)
        {
            return max;
        }

        if (input.CompareTo(max) &lt; 0)
        {
            return min;
        }

        return input;
    }

    public TextBoxNum(Value&lt;T&gt; value, T min, T max)
    {
        this.value = value;
        this.min = min;
        this.max = max;

        LostFocus += new EventHandler(Update);           
    }
}


Int variant:

public class TextBoxInt : TextBoxNum&lt;int&gt;
{
    public override void Update(object sender, EventArgs e)
    {
        int newValue;

        if (int.TryParse(Text, out newValue))
        {
            if (newValue &lt; min || newValue &gt; max)
            {
                newValue = Clamp(newValue);
            }

            value.Set(newValue);
            Text = value.Get().ToString();
        }

        else
        {
            Text = value.Get().ToString();
            Focus();
        }
    }

    public TextBoxInt(Value&lt;int&gt; value, int min, int max) : base(value, min, max)
    {

    }
}


UInt variant:

public class TextBoxUInt : TextBoxNum&lt;uint&gt;
{
    public override void Update(object sender, EventArgs e)
    {
        uint newValue;

        if (uint.TryParse(Text, out newValue))
        {
            if (newValue &lt; min || newValue &gt; max)
            {
                newValue = Clamp(newValue);
            }

            value.Set(newValue);
            Text = value.Get().ToString();
        }

        else
        {
            Text = value.Get().ToString();
            Focus();
        }
    }

    public TextBoxUInt(Value&lt;uint&gt; value, uint min, uint max) : base(value, min, max)
    {

    }
}


ULong variant:

public class TextBoxULong : TextBoxNum&lt;ulong&gt;
{
    public override void Update(object sender, EventArgs e)
    {
        ulong newValue;

        if (ulong.TryParse(Text, out newValue))
        {
            if (newValue &lt; min || newValue &gt; max)
            {
                newValue = Clamp(newValue);
            }

            value.Set(newValue);
            Text = value.Get().ToString();
        }

        else
        {
            Text = value.Get().ToString();
            Focus();
        }
    }

    public TextBoxULong(Value&lt;ulong&gt; value, ulong min, ulong max) : base(value, min, max)
    {

    }
}


Float variant:

public class TextBoxFloat : TextBoxNum&lt;float&gt;
{
    public override void Update(object sender, EventArgs e)
    {
        float newValue;

        if (float.TryParse(Text, out newValue))
        {
            if (newValue &lt; min || newValue &gt; max)
            {
                newValue = Clamp(newValue);
            }

            value.Set(newValue);
            Text = value.Get().ToString();
        }

        else
        {
            Text = value.Get().ToString();
            Focus();
        }
    }

    public TextBoxFloat(Value&lt;float&gt; value, float min, float max) : base(value, min, max)
    {

    }
}
class TextBoxNum


Abbreviation should be avoided when naming a class: Num -> Numeric
The descriptive adjective should also be in front of the noun. It is a numerical textbox, and not a textbox number: NumericTextBoxBase
TextBoxNum and Update should be marked as abstract, unless a generic way of updating the value is provided in TextBoxNum. And by changing it to a abstract class, we should append Base to the end of the class name : NumericTextBoxBase, and its concrete classes can be named as FloatTextBox, DoubleTextBox...




class Value&lt;T&gt;

Without the definition of this class, I can only make some guess about it. We can observe that the value is assigned by a parameter from the constructor. The class itself seems to serve no other purpose than holding the value via void Value&lt;T&gt;.Set(T) and T Value.Get(). I would suggest you to replace them by T or T?, depending on whether or not if you want to enforce valid value is required.



Misc


Avoid try-catch as control-structure much as possible, unless that is your last resort.
Your Clamp method is comparing the value against the same upper boundary, max, twice.




Code:

public class NumericTextBox&lt;T&gt; : TextBox where T : IComparable&lt;T&gt;
{
    protected T min;
    protected T max;
    protected T value;

    public NumericTextBox(T value, T min, T max)
    {
        this.min = min;
        this.max = max;

        // ensure the value is with in valid range
        this.value = Clamp(value);
        // actually you should implement a full property for value and update the Text property in the setter
        this.Text = value.ToString();

        LostFocus += new EventHandler(Update);
    }

    protected virtual void Update(object sender, EventArgs e)
    {
        var type = typeof(T);
        var tryParse = type.GetMethod("TryParse", new[]
        {
            typeof(string), type.MakeByRefType()
        });
        var args = new object[] { Text, null };
        var result = (bool)tryParse.Invoke(null, args);

        if (result)
        {
            value = Clamp((T)args[1]);
            Text = value.ToString();
        }
        else
        {
            Text = value.ToString();
            Focus();
        }
    }
    protected T Clamp(T input)
    {
        if (input.CompareTo(max) &gt; 0)
        {
            return max;
        }

        if (input.CompareTo(min) &lt; 0)
        {
            return min;
        }

        return input;
    }
}