值类型的字节宽度

时间:2009-02-18 14:20:29

标签: c# generics

我想将值类型传递给函数,并将其设置为整个变量宽度的重复位模式(FF,AA等)。现在,我用

传递值

void foo(T val)其中T:struct

所以我可以使用任何值类型。问题是,编译器不会让我使用sizeof(T),因为T可能是一个引用类型(除了它不能,这要归功于“where”约束)。我可以硬编码所有的值类型并自己检查它们,但这显然有点矫枉过正。有更简单的方法吗?

只是澄清一下:如果我传递byteInt64,我想将其设置为0xFFFFFFFF。

我尝试了Convert.ChangeType(0xFFFFFFFF, typeof(T)),但如果val是例如{}一个Char。我可以通过以下方法解决问题:a)确定类型参数的宽度和“构建”足够大的值,b)确定如何接受任何值类型(并且只有值类型),例如sizeof ()可以工作,或者c)弄清楚如何自动截断0xFFFFFFFF到变量的正确宽度。

4 个答案:

答案 0 :(得分:2)

你能使用Marshal.SizeOf方法吗?

http://msdn.microsoft.com/en-us/library/y3ybkfb3.aspx

编辑:NB!在实际执行此操作之前,请阅读Tor Haugen的评论。

答案 1 :(得分:1)

您也可以将-1转换为您正在处理的内容。无论变量的长度如何,-1始终都是F的。只要您使用原始类型,这绝不应该导致太多问题。

快速解释其原因:

系统中的所有整数都以2的补码表示法保存。这意味着负数不仅仅是带符号位的数字。要创建2的补码,只需翻转所有位并加1即可。

麦角:

-1 =不(1)+ 1

所以

<00> 0000 0001&gt; 1111 1110&gt; 1111 1111 = 0xFF

这将始终为您提供任何长度项目的全部1。

编辑:

使用sizeof运算符以字节为单位获取类型的大小,使用typeof来获取类型,然后我将在循环中使用位移来填充项目sooo ... < / p>

for (int i = 0; i < sizeof(typeof(input)); i++) 
{
  input = (input << 8) | Ox<Pattern>
}

请原谅我的句法错误,已经有一段时间了,但那应该做你想要的。

答案 2 :(得分:0)

您可以使用二进制序列化来获取大小,但是您必须序列化对象的两个数组,一个包含两个元素,一个包含一个元素,并从另一个元素中减去一个大小以消除序列化开销。请注意System.Decimal等类型,它们具有不同值的不同序列化长度。

答案 3 :(得分:0)

我以为自己已经做了什么 - sizeof()适用于结构体,但只适用于不安全的块。所以我试过了:

// compile with /unsafe
public unsafe void Foo<T>(T val) where T : struct
{
    // Works!
    int size1 = sizeof(SomeStruct);
    // Doesn't work, alas
    int size2 = sizeof(T);
}

看起来sizeof与泛型类型参数有关。所以不要去。

正如我在norheim.se的回答中所评论的,你应该知道Marshal.SizeOf()不一定会在运行时给你你的类型大小,所以我不推荐它。

对于不高雅的冒险,我会诚实地考虑一个简单的switch陈述。如果您的价值类型为库存int s,long s,byte等,则可以管理多种可能性。您应该记住,根据类型是否签名,设置位模式可能是一个不同的任务!切换将使处理这样的事情变得容易。