拆箱到未知类型 [英] Unboxing to unknown type
问题描述
我试图找出语法支持拆箱整型(短/ INT /长),其固有的类型,当类型本身是未知的。
I'm trying to figure out syntax that supports unboxing an integral type (short/int/long) to its intrinsic type, when the type itself is unknown.
下面是一个完全人为的例子,演示了这一概念:
Here is a completely contrived example that demonstrates the concept:
// Just a simple container that returns values as objects
struct DataStruct
{
public short ShortVale;
public int IntValue;
public long LongValue;
public object GetBoxedShortValue() { return ShortVale; }
public object GetBoxedIntValue() { return IntValue; }
public object GetBoxedLongValue() { return LongValue; }
}
static void Main( string[] args )
{
DataStruct data;
// Initialize data - any value will do
data.LongValue = data.IntValue = data.ShortVale = 42;
DataStruct newData;
// This works if you know the type you are expecting!
newData.ShortVale = (short)data.GetBoxedShortValue();
newData.IntValue = (int)data.GetBoxedIntValue();
newData.LongValue = (long)data.GetBoxedLongValue();
// But what about when you don't know?
newData.ShortVale = data.GetBoxedShortValue(); // error
newData.IntValue = data.GetBoxedIntValue(); // error
newData.LongValue = data.GetBoxedLongValue(); // error
}
在每一种情况下,整型是一致的,所以应该有某种形式的语法,上面写着对象包含一个简单的X型的,返回为X(虽然我不知道什么X是) 。因为对象最终都来自同一个源头,实在无法不匹配(短!=长)。
In each case, the integral types are consistent, so there should be some form of syntax that says "the object contains a simple type of X, return that as X (even though I don't know what X is)". Because the objects ultimately come from the same source, there really can't be a mismatch (short != long).
我的人为的例子道歉,这似乎是证明语法的最好方法。
I apologize for the contrived example, it seemed like the best way to demonstrate the syntax.
感谢。
推荐答案
那么,对象
本身就是最一般类型的框架知道。无论是是装箱值类型(包括原始)还是其他什么东西并不重要;如果你想获得更具体的您的有无的,除非你停留在宽松类型的世界做一个类型转换对象
(或者,在C# 4,动态
)。
Well, the object
in itself is the most generic type the framework knows. Whether is is a boxed value type (including primitive) or something else doesn't matter; if you want to get more specific you have to do a typecast unless you remain in the "loosely typed" world with object
(or, in C# 4, dynamic
).
但是请注意,您可以使用的条件列表来实现你想要的:
Note, however, that you can use a list of conditions to achieve what you want:
object boxedValue = GetBoxedValue();
if (typeof(short) == boxedValue.GetType()) {
newData.ShortValue = (short)boxedValue;
} else if (typeof(int) == boxedValue.GetType()) {
newData.IntValue = (int)boxedValue;
} else if (typeof(long) == boxedValue.GetType()) {
newData.LongValue = (long)boxedValue;
} else {
// not one of those
}
编辑::一种通用的盒子也可以做你想做的:
A generic "box" may also do what you want:
public class Box<T>: IConvertible where T: struct, IConvertible {
public static implicit operator T(Box<T> boxed) {
return boxed.Value;
}
public static explicit operator Box<T>(T value) {
return new Box<T>(value);
}
private readonly T value;
public Box(T value) {
this.value = value;
}
public T Value {
get {
return value;
}
}
public override bool Equals(object obj) {
Box<T> boxed = obj as Box<T>;
if (boxed != null) {
return value.Equals(boxed.Value);
}
return value.Equals(obj);
}
public override int GetHashCode() {
return value.GetHashCode();
}
public override string ToString() {
return value.ToString();
}
bool IConvertible.ToBoolean(IFormatProvider provider) {
return value.ToBoolean(provider);
}
char IConvertible.ToChar(IFormatProvider provider) {
return value.ToChar(provider);
}
sbyte IConvertible.ToSByte(IFormatProvider provider) {
return value.ToSByte(provider);
}
byte IConvertible.ToByte(IFormatProvider provider) {
return value.ToByte(provider);
}
short IConvertible.ToInt16(IFormatProvider provider) {
return value.ToInt16(provider);
}
ushort IConvertible.ToUInt16(IFormatProvider provider) {
return value.ToUInt16(provider);
}
int IConvertible.ToInt32(IFormatProvider provider) {
return value.ToInt32(provider);
}
uint IConvertible.ToUInt32(IFormatProvider provider) {
return value.ToUInt32(provider);
}
long IConvertible.ToInt64(IFormatProvider provider) {
return value.ToInt64(provider);
}
ulong IConvertible.ToUInt64(IFormatProvider provider) {
return value.ToUInt64(provider);
}
float IConvertible.ToSingle(IFormatProvider provider) {
return value.ToSingle(provider);
}
double IConvertible.ToDouble(IFormatProvider provider) {
return value.ToDouble(provider);
}
decimal IConvertible.ToDecimal(IFormatProvider provider) {
return value.ToDecimal(provider);
}
DateTime IConvertible.ToDateTime(IFormatProvider provider) {
return value.ToDateTime(provider);
}
string IConvertible.ToString(IFormatProvider provider) {
return value.ToString(provider);
}
object IConvertible.ToType(Type conversionType, IFormatProvider provider) {
return value.ToType(conversionType, provider);
}
}
这可以用来对象
代替;它仍然是一个对象的引用,但它也是强类型的原有结构和基本类型。
This can then be used instead of object
; it is still an object reference but it is also strongly typed to the original structure or primitive type.
这篇关于拆箱到未知类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!