我想将值类型传递给函数,并将其设置为整个变量宽度的重复位模式(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到变量的正确宽度。
答案 0 :(得分:2)
你能使用Marshal.SizeOf方法吗?
编辑: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
等,则可以管理多种可能性。您应该记住,根据类型是否签名,设置位模式可能是一个不同的任务!切换将使处理这样的事情变得容易。