C# 是否可以将对象取消装箱到多个值类型?

C# 是否可以将对象取消装箱到多个值类型?,c#,C#,我已通过C#在CLR中阅读: 取消装箱实际上只是获取指向 对象中包含的原始值类型(数据字段) 这意味着,如果一个对象中包含多个值类型,则可以使用以下语法将其解除绑定: int a= (int) o; //assigns a to 10 char b= (char) o; // assigns b to 'b' 如何实现这样一个支持多重取消装箱的对象?如果您有一个自定义对象,例如同时包含int或string,您可以使用 榜样 public class CustomObject { int

我已通过C#在CLR中阅读:

取消装箱实际上只是获取指向 对象中包含的原始值类型(数据字段)

这意味着,如果一个对象中包含多个值类型,则可以使用以下语法将其解除绑定:

int a= (int) o; //assigns a to 10
char b= (char) o; // assigns b to 'b'

如何实现这样一个支持多重取消装箱的对象?

如果您有一个自定义对象,例如同时包含int或string,您可以使用

榜样

public class CustomObject
{
    int Number;
    string Text;

    public CustomObject(int number, string text)  //constructor
    {
        Number = number;
        Text = text;
    }

    public static explicit operator int(CustomObject o)
    {
        return o.Number;
    }

    public static explicit operator string(CustomObject o)
    {
        return o.Text;
    }
}

你说的是铸造吗?在.NET中,如果您有一个装箱类型,则它有一个特定类型,并且您只能将其强制转换为要取消装箱的实际值类型:

object o=10;               // o is a boxed int with value 10
var a=(int)o;              // works
//var b=(byte)o;           // ERROR, this is not what's contained in it
var b=(byte)(int)o;        // works, you get the int out then cast it to byte
var b=Convert.ToByte(o);   // also works, using IConvertible

然而,泛型的主要目的(至少最初)是为了避免装箱值类型,因为这涉及到性能成本。您可以将
对象的大多数实例更改为泛型值并保留类型,当您使用它们时,您将立即获得正确的值类型。

装箱的值只能是单个类型的装箱形式-如果调用
o.GetType()
,您将发现这是什么

通常,您只能取消装箱到完全相同的类型,但有一些褶皱:

  • 可以将枚举值取消绑定到其基础整数类型,反之亦然
  • 不存在装箱的可空值类型—装箱将导致非可空类型的装箱形式或空引用。您可以取消绑定到一个可为null的值类型,结果要么是null值(如果原始引用是null引用),要么是包含未绑定的不可为null值的非null值,如果您明白我的意思的话
例如:

object o = 10;
FileMode mode = (FileMode) o; // Valid conversion to enum

int? n = (int?) o; // n has a value of 10
n = null;
o = n; // o's value is a null reference
n = (int?) o; // n's value is the null int? value


你能举个例子(可能是伪代码)说明你想做什么吗?没有“一个对象中包含多个值类型”这样的概念如果对象是装箱的值。如果您为
o
@JonSkeet指定int或char,该代码将抛出一个
InvalidCastException
,谢谢…您能在答案中复制您的注释,以便我可以接受它吗。你真好…也许你在找什么?与装箱无关,但听起来像是您想要的。我真的不这么认为,您只能取消装箱到对象“box”中包含的值类型。这是一个类,因此不会装箱。从
对象
进行的强制转换不会使用该类型定义的显式转换。基本上,它回答了一个与所问问题不同的问题。是的,术语不同。我的目的是给出一个例子,说明如何实现问题中描述的所要求的可用性。该要求使用了
对象
和取消绑定,但您的答案根本不符合这些要求。是的,我有一个错误的概念,即将引用类型转换为值类型称为取消绑定,但我意识到这只适用于system.Object引用类型。如果您看到我提供的定义,它说值类型是包含在对象中的数据字段。如果这是真的,为什么我们不能在一个对象中有多个数据字段?我想我已经知道了…我的问题的答案是肯定的或否定的。如果是,那么就实现它。我不同意,你的问题的答案是一个困惑的表达式。我们都在猜测你的真正意思,但如果这不是真的,你真的认为你可以在一个手柄中同时握住两个物体,那么答案是“不”。我的问题很直截了当。它只是“你能将一个对象取消绑定到多个值类型吗?”。不能,你只能将一个值取消绑定到它包含的类型。这是我在回答中说的第一句话。是的,但我的疑问是一个对象是否可以包含多个值类型。根据“clr via c#”,值类型作为数据字段存储在对象中。这让我想到,为什么不能有一个以上的数据字段??如果您能回答这个问题,这将非常有帮助。
您可以将有符号原语取消装箱为其等效的无符号类型(例如int/uint),反之亦然
。它为我抛出了
InvalidCastException
。@PetSerAl:你完全正确。哎呀。将删除该位-与数组混淆。(你可以通过
object
int[]
转换到
uint[]
,反之亦然)@JonSkeet那么Avilan的答案呢。在我看来这是正确的。你能复习一下吗?@DeepakMishra:那是一种引用类型,所以永远不会被装箱。即使它是一个结构,当它被装箱时,原始类型也会被装箱,因此要将装箱的表单转换为
int
,您需要一个双强制转换-一到unbox,另一个调用自定义转换。抱歉…我有一个错误的想法,将引用类型转换为值类型就是取消绑定,但根据MSDN:取消绑定是从类型对象到值类型的显式转换,或者从接口类型到实现接口的值类型的显式转换。我在“CLR通过C#”中找不到这个定义。谢谢你澄清这一点。