In C#, writing special cases for native types is typically done by method overloading. There are several places in the BCL where you can see this kind of design, one example being the BitConverter
class.
If you want a generic version with a few special cases, you can add a generic overload and C#'s type inference will make it transparent to the end user.
public decimal shift(int input, byte b)
{
//....
}
public decimal shift(uint input, byte b)
{
//....
}
public decimal shift<T>(T input, byte b)
{
//....
}
Usage:
shift(5, 1); //resolves to the 'int'overload
shift(5u, 1); //resolves to the 'uint' overload
shift(new Point(2, 2), 1) //resolves to the generic overload with T = Point
I'm guessing you're trying to do bit shifting with a generic method. There are only a handful of types that this makes sense for (byte, sbyte, short, ushort, int, uint, long, ulong), so you might as well just write out the 8 overloads. I have a class in one of my projects that includes a lot of bit hacks, and I just write out the necessary overloads and it works out pretty well.