如何在C#中获取类型的位宽和符号?

时间:2012-03-02 01:41:26

标签: c# types

我需要获取类型的数据位宽。我怎么能得到它? 例如,我如何编写如下函数?

int x = 30;
Type t = x.GetType();
bool sign = IsSignedType(t); // int is signed type, so it's true
int width = GetWidth(t); // 32

2 个答案:

答案 0 :(得分:4)

对于大小,你可以使用Marshal.SizeOf并乘以一个字节中的位数(提示:8),但对于内置值类型,它可能很容易,而且使用起来肯定更快案例陈述。

对于标志,我认为bool sign = t == Math.Abs(t);会这样做。

编辑:

要确定是否为带符号的号码,没有内置方法,但只有 3 5:

public static class Application
{
    public enum SignedEnum : int
    {
        Foo,
        Boo,
        Zoo
    }

    public enum UnSignedEnum : uint
    {
        Foo,
        Boo,
        Zoo
    }

    public static void Main()
    {
        Console.WriteLine(Marshal.SizeOf(typeof(Int32)) * 8);
        Console.WriteLine(5.IsSigned());
        Console.WriteLine(((UInt32)5).IsSigned());
        Console.WriteLine((SignedEnum.Zoo).IsSigned());
        Console.WriteLine((UnSignedEnum.Zoo).IsSigned());

        Console.ReadLine();
    }
}

public static class NumberHelper
{
    public static Boolean IsSigned<T>(this T value) where T : struct
    {
        return value.GetType().IsSigned();
    }

    public static Boolean IsSigned(this Type t)
    {
        return !(
            t.Equals(typeof(Byte)) ||
            t.Equals(typeof(UIntPtr)) ||
            t.Equals(typeof(UInt16)) ||
            t.Equals(typeof(UInt32)) ||
            t.Equals(typeof(UInt64)) ||
            (t.IsEnum && !Enum.GetUnderlyingType(t).IsSigned())
            );
    }
}

答案 1 :(得分:2)

@ ChrisShain正确回答了第一部分。假设您可以保证t是数字类型,要判断该类型是否已签名,您应该能够使用表达式树动态调用MaxValue上的t const字段,将它转换为一个bitarray并检查它是否使用符号位(或者只使用bitshift magic来测试它而不进行转换)。我没有这样做,但它应该是可行的。如果你想要一个例子,我可以解决它。

或者像其他人一样使用switch语句(或if系列语句)轻松实现。