2012-03-02 53 views
1

我需要获取某个类型的数据位宽。我怎么弄到的? 例如,我如何编写一个函数如下?如何获取C#中的位宽和类型符号?

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

您是否试图获取值的*符号*,或者值是否为* signed *类型? – Gabe 2012-03-02 01:54:45

+0

我需要得到,如果类型是签名类型或不。 – prosseek 2012-03-02 02:01:27

+0

@prosseek这就是为什么我们使用有意义的变量名称 - 请参阅M.Babcock对我的回答的评论:-) – 2012-03-02 02:03:15

回答

4

对于尺寸,你可以使用Marshal.SizeOf,并在一个字节由位的数量乘以(提示:8),虽然对内置值类型是足够的,当然更快地只使用可能容易一个案例陈述。我想bool sign = t == Math.Abs(t);会做。

编辑:

以确定它是否是签署数,没有内置的方法,但只有其中的 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()) 
      ); 
    } 
} 
+0

虽然'sign'有点模棱两可我可能会用'isPositive'之类的东西。 – 2012-03-02 01:57:24

+0

同意有意义的变量名称。 “符号”是他的。 – 2012-03-02 02:02:27

+0

忽略了这一点,够公平的。 – 2012-03-02 02:03:08

2

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

或者像其他人那样使用switch声明(或系列if)轻松实现。