What you could do is create a generic interface that includes the operations that you want to support, create a generic factory to create instances for the supported types to perform the operations, and use it.
e.g.,
public interface IOperations<T>
{
    T Add(T a, T b);
    T Subtract(T a, T b);
    T Multiply(T a, T b);
    T Divide(T a, T b);
}
public static class Operations<T>
{
    public static IOperations<T> Default { get { return Create(); } }
    static IOperations<T> Create()
    {
        var type = typeof(T);
        switch (Type.GetTypeCode(type))
        {
        case TypeCode.Byte:
            return (IOperations<T>)new ByteOperations();
        case TypeCode.Single:
            return (IOperations<T>)new SingleOperations();
        default:
            var message = String.Format("Operations for type {0} is not supported.", type.Name);
            throw new NotSupportedException(message);
        }
    }
    class ByteOperations : IOperations<byte>
    {
        public byte Add(byte a, byte b)      { return unchecked ((byte)(a + b)); }
        public byte Subtract(byte a, byte b) { return unchecked ((byte)(a - b)); }
        public byte Multiply(byte a, byte b) { return unchecked ((byte)(a * b)); }
        public byte Divide(byte a, byte b)   { return unchecked ((byte)(a / b)); }
    }
    class SingleOperations : IOperations<float>
    {
        public float Add(float a, float b)      { return a + b; }
        public float Subtract(float a, float b) { return a - b; }
        public float Multiply(float a, float b) { return a * b; }
        public float Divide(float a, float b)   { return a / b; }
    }
}
T Mean<T>(IList<T> numbers)
{
    var operations = Operations<T>.Default;
    var sum = numbers.Aggregate(operations.Add);
    var count = (T)Convert.ChangeType(numbers.Count, typeof(T));
    return operations.Divide(sum, count);
}
var resultByte = Mean(new byte[] { 1, 2, 3, 4 });                // 2
var resultSingle = Mean(new float[] { 1.1F, 2.1F, 3.1F, 4.1F }); // 2.6F
var resultInt = Mean(new int[] { 1, 2, 3, 4 });                  // not supported
If you don't mind a small performance hit, you could dynamically create the operations needed.
class GenericOperations<T> : IOperations<T>
{
    public GenericOperations()
    {
        add = CreateLambda(Expression.Add);
        subtract = CreateLambda(Expression.Subtract);
        multiply = CreateLambda(Expression.Multiply);
        divide = CreateLambda(Expression.Divide);
    }
    private Func<T, T, T> add, subtract, multiply, divide;
    private static Func<T, T, T> CreateLambda(Func<Expression, Expression, BinaryExpression> op)
    {
        var a = Expression.Parameter(typeof(T), "a");
        var b = Expression.Parameter(typeof(T), "b");
        var body = op(a, b);
        var expr = Expression.Lambda<Func<T, T, T>>(body, a, b);
        return expr.Compile();
    }
    public T Add(T a, T b)      { return add(a, b); }
    public T Subtract(T a, T b) { return subtract(a, b); }
    public T Multiply(T a, T b) { return multiply(a, b); }
    public T Divide(T a, T b)   { return divide(a, b); }
}