Reb*_*bin 25 .net c# boxing dynamic
我正在寻找一种编写代码来测试值是否已装箱的方法.
我的初步调查表明,.NET不顾一切地隐瞒事实,这意味着GetType()并IsValueType没有揭示盒装值和未装箱值之间的差异.例如,在下面的LinqPad C#表情,我有信心o1在盒装和i1没有盒装,但是我想一个方法来测试它的代码,或者退而求其次,就无从知道肯定看任何变量时或值,即使它的类型是"动态"或"对象",无论是盒装还是不盒装.
有什么建议?
// boxed? -- no way to tell from these answers!
object o1 = 123;
o1.GetType().Dump("o1.GetType()");
o1.GetType().IsValueType.Dump("o1.GetType().IsValueType");
// not boxed? -- no way to tell from these answers!
int i1 = 123;
i1.GetType().Dump("i1.GetType()");
i1.GetType().IsValueType.Dump("i1.GetType().IsValueType");
Run Code Online (Sandbox Code Playgroud)
Jar*_*Par 33
请尝试以下方法
public static bool IsBoxed<T>(T value)
{
return
(typeof(T).IsInterface || typeof(T) == typeof(object)) &&
value != null &&
value.GetType().IsValueType;
}
Run Code Online (Sandbox Code Playgroud)
通过使用泛型,我们允许函数考虑编译器查看的表达式类型及其底层值.
Console.WriteLine(IsBoxed(42)); // False
Console.WriteLine(IsBoxed((object)42)); // True
Console.WriteLine(IsBoxed((IComparable)42)); // True
Run Code Online (Sandbox Code Playgroud)
编辑
有几个人要求澄清为什么这需要通用.并质疑为什么甚至需要它,开发人员不能只看代码并判断一个值是否装箱?为了回答这两个问题,请考虑以下方法签名
void Example<T>(T param1, object param2, ISomething param3) where T : ISomething {
object local1 = param1;
ISomething local2 = param1;
...
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,任何提供的参数或本地可能代表盒装值,并且可能很容易.通过临时检查无法判断,只检查运行时类型和保持值的引用的组合可以确定.
好吧,让我们用诀窍......
我们知道什么?
所以我们只检查它是否再次被装箱(进入另一个对象)......所以我们比较一下参考文献
isReferenceType这里将是假的,因为我们比较堆上的两个对象(一个盒装surelyBoxed,一个盒装只是在调用ReferenceEquals):
int checkedVariable = 123; //any type of variable can be used here
object surelyBoxed = checkedVariable;
bool isReferenceType = object.ReferenceEquals(surelyBoxed, checkedVariable);
Run Code Online (Sandbox Code Playgroud)
isReferenceType这将是真的,因为我们将堆上的1个对象与自身进行比较:
object checkedVariable = 123; //any type of variable can be used here
object surelyBoxed = checkedVariable;
bool isReferenceType = object.ReferenceEquals(surelyBoxed, checkedVariable);
Run Code Online (Sandbox Code Playgroud)
这适用于任何类型,而不仅仅是int和object
把它放入很好用的方法:
public static bool IsReferenceType<T>(T input)
{
object surelyBoxed = input;
return object.ReferenceEquals(surelyBoxed, input);
}
Run Code Online (Sandbox Code Playgroud)
这种方法可以很容易地使用:
int i1 = 123;
object o1 = 123;
//...
bool i1Referential = IsReferenceType(i1); //returns false
bool o1Referential = IsReferenceType(o1); //returns true
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4384 次 |
| 最近记录: |