简单的方法来检查原始数据类型是否为"可以安全地放入原始数据类型"(假设两者的签名相同)
本文关键字:原始 数据类型 quot 假设 是否 检查 方法 安全 简单 | 更新日期: 2023-09-27 18:02:09
给定此函数:
bool WillDataTypeFit(Type typeToCheck, Type typeToFitInto)
{
bool bWillFit = false;
// Psedocode
// IF typeToCheck is NOT the same as typeToFitInfo
// IF typeToCheck && typeToFitInfo are signed
// Check for signed fit
// ELSE IF typeToCheck && typeToFitInfo are unsigned
// Check for unsigned fit
// ELSE
// bWillFit = true;
return (bWillFit);
}
是否有一个简单的方法来看看typeToCheck
是否可以安全地适合typeToFitInto
?
我关心的是原始数据类型,不包括DateSpan
, DateTime
, bool
, decimal
, string
, char
, object
也就是signed/unsigned int
float
double
编辑:
"Fit into"意味着我可以安全地将typeToCheck
的最大/最小值转换为typeToFitInto
的类型,但是在此检查时,我没有任何值可以转换,所以我试图简单地检查数据类型
EDIT2:
我已经意识到这个问题通常是有缺陷的,因为没有一个值,你不能保证像一个正的sbyte
适合于byte
,我编辑了这个问题,所以只有当两种数据类型具有相同的签名时才会评估检查
据我所知没有简单的方法。您将需要这样的内容:
bool WillDataTypeFit(Type typeToCheck, Type typeToFitInto)
{
if (typeToCheck.Equals(typeToFitInto))
{
return true;
}
else if (typeToCheck == typeof(sbyte))
{
if (typeToFitInto == typeof(short))
return true;
else if (typeToFitInto == typeof(int))
return true;
else if (typeToFitInto == typeof(long))
return true;
else if (typeToFitInto == typeof(float))
return true;
else if (typeToFitInto == typeof(double))
return true;
else if (typeToFitInto == typeof(decimal))
return true;
else
return false;
}
else if (typeToCheck == typeof(byte))
{
if (typeToFitInto == typeof(short))
return true;
else if (typeToFitInto == typeof(ushort))
return true;
else if (typeToFitInto == typeof(int))
return true;
else if (typeToFitInto == typeof(uint))
return true;
else if (typeToFitInto == typeof(long))
return true;
else if (typeToFitInto == typeof(ulong))
return true;
else if (typeToFitInto == typeof(float))
return true;
else if (typeToFitInto == typeof(double))
return true;
else if (typeToFitInto == typeof(decimal))
return true;
else
return false;
}
else if (typeToCheck == typeof(ushort))
{
if (typeToFitInto == typeof(int))
return true;
else if (typeToFitInto == typeof(uint))
return true;
else if (typeToFitInto == typeof(long))
return true;
else if (typeToFitInto == typeof(ulong))
return true;
else if (typeToFitInto == typeof(float))
return true;
else if (typeToFitInto == typeof(double))
return true;
else if (typeToFitInto == typeof(decimal))
return true;
else
return false;
}
else if (typeToCheck == typeof(short))
{
if (typeToFitInto == typeof(int))
return true;
else if (typeToFitInto == typeof(long))
return true;
else if (typeToFitInto == typeof(float))
return true;
else if (typeToFitInto == typeof(double))
return true;
else if (typeToFitInto == typeof(decimal))
return true;
else
return false;
}
else if (typeToCheck == typeof(uint))
{
if (typeToFitInto == typeof(long))
return true;
else if (typeToFitInto == typeof(ulong))
return true;
else if (typeToFitInto == typeof(float))
return true;
else if (typeToFitInto == typeof(double))
return true;
else if (typeToFitInto == typeof(decimal))
return true;
else
return false;
}
else if (typeToCheck == typeof(int))
{
if (typeToFitInto == typeof(long))
return true;
else if (typeToFitInto == typeof(float))
return true;
else if (typeToFitInto == typeof(double))
return true;
else if (typeToFitInto == typeof(decimal))
return true;
else
return false;
}
else if (typeToCheck == typeof(long) || typeToCheck == typeof(ulong))
{
if (typeToFitInto == typeof(float))
return true;
else if (typeToFitInto == typeof(double))
return true;
else if (typeToFitInto == typeof(decimal))
return true;
else
return false;
}
else if (typeToCheck == typeof(float))
{
if (typeToFitInto == typeof(double))
return true;
else
return false;
}
else
{
return false;
}
}
我相信这是详尽的数字类型,但你可以在这里检查隐式数字转换
如果您可以将自己限制为只使用结构体,则可以滥用dynamic
关键字进行检查。
class Program
{
static void Main(string[] args)
{
Console.WriteLine(WillDataTypeFit<short, int>());
Console.WriteLine(WillDataTypeFit<int, short>());
}
static bool WillDataTypeFit<TTypeToCheck, TTypeToFitInto>()
where TTypeToCheck : struct
where TTypeToFitInto : struct
{
TTypeToCheck typeToCheck = default(TTypeToCheck);
dynamic test = typeToCheck;
try
{
TTypeToFitInto toFitInto = test;
}
catch (Exception)
{
return false;
}
return true;
}
}
如果你使用float, byte等类型,你总是可以使用"sizeof "。考虑:
Console.WriteLine(sizeof(bool)); // 1
Console.WriteLine(sizeof(byte)); // 1
Console.WriteLine(sizeof(short)); // 2
Console.WriteLine(sizeof(int)); // 4
Console.WriteLine(sizeof(long)); // 8
我可以用Marshall。struct的SizeOf,例如
private struct Temp
{
public int a { get; set; }
public int b { get; set; }
public int c { get; set; }
public Temp(int a, int b, int c)
{
this.a = a;
this.b = b;
this.c = c;
}
}
Console.WriteLine(Marshal.SizeOf(new Temp(1, 2, 3))); // 12
所以你可以用这个来做比较(取决于你想比较的类型;这绝对适用于像结构体、整型等值类型,但对于纯托管引用类型,它似乎会崩溃;你肯定会不能在List类上执行sizeof,因为它的大小不一定是静态的)。
为了更直接地解决你的问题,请特别注意sizeof(int)
顺便说一下,在这种情况下,"适合"是一个反对称的、自反的和传递的关系,所以它可以被认为是。net类型上的偏序。(这不是一个完整的顺序,因为它没有对引用类型进行排序)。
有两种可行的方法:
- 查看类型是否可以隐式浇注,就像这篇文章的讨论一样
- 使用反射来比较数值类型的静态MinValue和MaxValue属性。
- 按照前面的答案建议使用硬编码字典或查找。如果你关心的唯一类型集是(int, int, float, double, long, ulong),这可能是最简单和最高效的。