C# overload method simplification I have the following routine that I would like to simplify:

public void SetUniform(RenderContext ctx, string uName, object value)
{
    if (ctx == null)
        throw new ArgumentNullException("ctx");
    if (value == null)
        throw new ArgumentNullException("value");

    if (value is int)
        SetUniform(ctx, uName, (int)value);
    else if (value is Vertex2f)
        SetUniform(ctx, uName, (Vertex2f)value);
    else if (value is Vertex3f)
        SetUniform(ctx, uName, (Vertex3f)value);
    else if (value is Vertex4f)
        SetUniform(ctx, uName, (Vertex4f)value);
    else if (value is Matrix4x4)
        SetUniform(ctx, uName, (Matrix4x4)value);
    else
        throw new NotSupportedException(value.GetType() + " is not supporteds");
}


As you can read, the above routine is essentially the generic version of all SetUniform. I need this routine becuase I don't know the value type at compile time, but in this way I need to check its type at runtime each time I need it.

How can I reduce this routine is a more simple and performant-wise way?



Due the comments, I need to clarify some question that seems not enought clear.


The "Uniform" state belongs to a specific class ShaderProgram, not to a wide set of classes (the ones listed on the snippet above are only a subset). Each SetUniform implementation access to the internal state of ShaderProgram, which I would not like expose, even using an internal modifier.
The SetUniform overload with object parameter is required because I get the value  using reflection, indeed I have no idea at compile time what is the value type. Indeed I have defined an additional overload which recall specific implementation.
Each SetUniform overload have a different implementation. Specifically, they call the one of the routines specified here.
You can overload your SetUniform method with the different types of value:

public void SetUniform(int value)
{

}
public void SetUniform(Vertex2f value)
{

}
public void SetUniform(Vertex3f value)
{

}
...


You could also try using the Null Object Pattern to avoid the null checks or define some default behaviour.