.net 一个人怎么能检查“你的”呢;“安全”;NET中值类型之间的转换?
回到最基本的 对于引用类型,可以执行以下操作:.net 一个人怎么能检查“你的”呢;“安全”;NET中值类型之间的转换?,.net,math,algebra,.net,Math,Algebra,回到最基本的 对于引用类型,可以执行以下操作: SomeType someObject = firstObject as SomeType; if (someObject == null) { // Handle the situation gracefully } else { // Do stuff } 对于值类型,我的理解是,我们
SomeType someObject = firstObject as SomeType;
if (someObject == null)
{
// Handle the situation gracefully
}
else
{
// Do stuff
}
对于值类型,我的理解是,我们有隐式转换(无数据丢失)、显式转换(如果存在数据丢失风险,则需要)、转换类(我认为是“转换包装器”)以及特定类型的转换(例如,double x=double.Parse(“2”);
),但是我还没有找到与上面的as
操作符类似的东西
因此,我的问题是:框架是否提供了一些方法/操作员/技术来按照以下思路进行操作:
if (!Convert.CanConvert(someValue, someValueType))
{
// Beware! Data loss can occur
}
else
{
// No data loss here
}
如果没有,有人能提出一个可靠的方法来构建这样一个CanConvert
方法吗
非常感谢
编辑(1):用户案例/问题如下:给定代码的使用者(我的另一个自我,但这并不相关)传递的某个内容,(1)检查某个内容是否是数字(足够简单),以及(2)将某个内容放在适合的“最小”数字类型中,而不会导致数据丢失
一些背景:我试图做的本质是数学而不是技术:我试图看看是否/如何将现有的数字类型放入某种代数层次结构中,形式为Monoid=>Group=>Ring=>Field(或其简化版本)。在进行这项工作时,我不太清楚如何“一件事导致另一件事”,我发现自己必须处理类型转换…关于各种值类型的TryParse方法如何
int x;
if (int.TryParse(someType.ToString(), out x))
return x;
as
运算符基于继承,值类型不继承。您可能会编写一个CanConvert()
,但它必须使用装箱的值类型,并且您通常希望避免装箱
所以,可能的:是的,可取的:不是
也许您可以添加一个用例场景,在其中您想要使用它,然后我们可以推荐替代方案
Re:编辑(1)
我希望你们知道,数字类型的系统主要是历史的包袱,不遵循逻辑规则。例如,没有像short
计算这样的东西,它们总是在做任何事情之前转换为int
但也许你可以用环和场来定义这种行为,代数对我来说已经“很久过去了” 看看
Convert.ChangeType
。您可以劫持它以满足您的目的,但由于异常引发和重复转换,它会很慢。as关键字基本上是一个安全的向下转换。由于所有值类型都是密封的,因此无法从中继承
所以你的代码应该是:
if (firstObject is MyValueType)
{
MyValueType obj = (MyValueType) firstObject;
}
else
{
}
我认为你误解了as操作员的观点。as运算符大致相当于以下代码:
if (firstObject is SomeType)
return (SomeType)firstObject;
else
return null;
所以更多的是继承检查。(如List)
值类型不支持继承,这是有充分理由的。Double和Int64都以完全不同的方式存储数字1
基本上,您需要的是一种方法,它将为您确定数字转换是否是无损失的。我用“为什么”来反驳。虽然CLR支持多种格式,但转换规则通常非常简单。例如,Int32->Double是无损的,从“较小”到“较大”的任何转换都是无损的,例如SByte->Int64
另一个问题是,在你的例子中,错误意味着什么?我想说的很少,例如:
Convert.CanConvert(123456789.12345F, typeof(Byte))
错误的结果有什么用?您的意思是,它适用于Int32->Single这样的情况,其中一些数据会丢失,但在这种情况下,大量数据会丢失,因为“最接近”的字节表示形式是255
正是因为这两个问题,才没有这样的方法。亨克几乎是在花钱。如果我愿意的话,我想对他的回答补充一点: NET Framework中的值类型转换使用
IConvertible
接口工作。Convert
类几乎在其所有方法中都使用了这种方法。这与C#中的隐式/显式转换运算符非常不同,后者只是另一种形式的语法糖
如果你这样写:
public struct Duck
{
public static implicit operator Goose(Duck d)
{
...
}
}
.NET框架本身不知道这是否存在。它以op_implicit
的形式发出,由编译语言决定如何使用它。并不是每种MSIL语言都支持这些。因此,该代码起作用:
Goose g1 = duck;
此代码不会:
Goose g1 = (Goose)Convert.ChangeType(duck, typeof(Goose));
为了实现能够识别隐式/显式转换运算符的
CanConvert
方法,实际上必须使用反射来检查各个op
方法,我不得不建议不要这样做——我看它在实践中没有什么用处。不过你需要最后一个结束语。谢谢——我在发帖前检查了它,我同意,它看起来对我的目的不太好。哦,是的,我想任何曾经在计算机中使用过数字的人都知道它们不遵循非常合乎逻辑的规则。所以我在这里建立我自己的。在我的家里,当然…:-)Re:你的编辑-我实际上做了一些类似的事情作为内联压缩算法的一部分。我的方法?从一个long
开始,将其与byte.MaxValue
进行比较,然后是short.MaxValue
,然后是int.MaxValue
,并将其转换为适合的最小值!根据下面Rob的建议,我正在尝试类似的方法。同样的想法:尝试按照一个预定义的顺序(我认为任何未签名)比任何因数学原因而签署的转换更小,即使内存明智这是不正确的。顺便问一下:你有什么网站/博客可以让我检查你的算法吗?