是否有任何方法可以在运行时将所需的类对象强制转换为另一个类对象,而无需在.net中直接强制转换?

是否有任何方法可以在运行时将所需的类对象强制转换为另一个类对象,而无需在.net中直接强制转换?,.net,object,casting,runtime,.net,Object,Casting,Runtime,例如,我有: class BasePacket { int header; int type; } class ChildPacket1 : BasePacket { //... } class ChildPacket2 : BasePacket { //... } BasePacket bp; Type t; object obj = CreateNeededChildPacket(out t); //return one of childs as object

例如,我有:

class BasePacket
{
   int header;
   int type;
}

class ChildPacket1 : BasePacket
{
   //...
}

class ChildPacket2 : BasePacket
{
   //...
}

BasePacket bp;
Type t;
object obj = CreateNeededChildPacket(out t); //return one of childs as object and it's real type
bp = ...// anyway to cast obj to type represented by t? or by using something else?
可以非常有效地处理各种类型转换场景,包括此场景,但需满足以下条件:

读者必须理解Convert.ChangeType()仅适用于 某些标准.NET系统类型。它对任何人都不起作用 未实现IConvertible且不工作的组件 用于自定义类型

请注意,在您的特定示例中,在两种值类型之间进行转换时,
ChangeType
的效率不如直接强制转换,因为
ChangeType
返回作为对象装箱的整数值

如果类实现了
IConvertable
,则可以将
ChangeType
用于您自己的类,例如

public class MyClass : IConvertible
{
    public float MyFloatValue { get; set; }

    int IConvertible.ToInt32(IFormatProvider provider)
    {
        return (int)MyFloatValue;
    }

    // TODO: Implement the rest of IConvertable
}

MyClass myClass = new MyClass() { MyFloatValue = 42.42f };
i = (int) Convert.ChangeType(myClass, t);
Console.WriteLine(i);
可以非常有效地处理各种类型转换场景,包括此场景,但需满足以下条件:

读者必须理解Convert.ChangeType()仅适用于 某些标准.NET系统类型。它对任何人都不起作用 未实现IConvertible且不工作的组件 用于自定义类型

请注意,在您的特定示例中,在两种值类型之间进行转换时,
ChangeType
的效率不如直接强制转换,因为
ChangeType
返回作为对象装箱的整数值

如果类实现了
IConvertable
,则可以将
ChangeType
用于您自己的类,例如

public class MyClass : IConvertible
{
    public float MyFloatValue { get; set; }

    int IConvertible.ToInt32(IFormatProvider provider)
    {
        return (int)MyFloatValue;
    }

    // TODO: Implement the rest of IConvertable
}

MyClass myClass = new MyClass() { MyFloatValue = 42.42f };
i = (int) Convert.ChangeType(myClass, t);
Console.WriteLine(i);

在您的示例中,您正在创建两个派生类中的一个,并将其存储在一个基变量中……这根本不需要任何强制转换,因为根据继承定律这样做是完全正确的。基类变量总是可以被分配一个更派生的对象,因为基类能够做的任何事情都可以保证派生类也能做,所以它是安全的。例如,数学教师可以执行普通教师可以执行的任何操作(例如成绩纸()。将教师变量指向数学教师对象是安全的

BasePacket bp = (BasePacket) CreateNeededChildPacket();

编辑: 为了响应您的评论,理想情况下,您应该让createNeedChildPacket()方法返回BasePacket类型(如果返回的对象总是从BasePacket中删除)。正如基参数可以接受派生对象一样,基返回类型可以返回派生对象,这就是继承的美妙之处。这将是更安全的人在道路上调用您的方法

BasePacket CreateNeededChildPacket() 
{
    // do something
    return AnyObjectThatDerivesFromBasePacket;    
}

如果无法更新该方法,则可以添加一些额外的类型检查,以确保安全

object obj = CreateNeededChildPacket();
BasePacket bp = null;

if (obj is BasePacket) 
   bp = (BasePacket) obj;
else
   throw new Exception("Object was not a valid BasePacket type: " + obj.GetType.ToString());

在您的示例中,您正在创建两个派生类中的一个,并将其存储在一个基变量中……这根本不需要任何强制转换,因为根据继承定律这样做是完全正确的。基类变量总是可以被分配一个更派生的对象,因为基类能够做的任何事情都可以保证派生类也能做,所以它是安全的。例如,数学教师可以执行普通教师可以执行的任何操作(例如成绩纸()。将教师变量指向数学教师对象是安全的

BasePacket bp = (BasePacket) CreateNeededChildPacket();

编辑: 为了响应您的评论,理想情况下,您应该让createNeedChildPacket()方法返回BasePacket类型(如果返回的对象总是从BasePacket中删除)。正如基参数可以接受派生对象一样,基返回类型可以返回派生对象,这就是继承的美妙之处。这将是更安全的人在道路上调用您的方法

BasePacket CreateNeededChildPacket() 
{
    // do something
    return AnyObjectThatDerivesFromBasePacket;    
}

如果无法更新该方法,则可以添加一些额外的类型检查,以确保安全

object obj = CreateNeededChildPacket();
BasePacket bp = null;

if (obj is BasePacket) 
   bp = (BasePacket) obj;
else
   throw new Exception("Object was not a valid BasePacket type: " + obj.GetType.ToString());

如果你能提供更多的背景,那会很有帮助。如果您事先知道
i
的类型,那么
t
在哪里出现?如果
t
是除
int
以外的任何类型,那就没有意义了,是吗?当然t可以是任何类型。更重要的是,对我来说,它将是手工制作的类型,而不是原生的.net类型。更重要的是,我本身应该是手工制作的类型,所以如果您试图分配一个
int
变量,但是
t
MyCustomType
,那么您希望如何处理转换?这正是我需要的转换示例。在我的例子中,我是父类,我需要分配子类的值,在编译过程中我不知道,您希望调用什么代码来执行转换?基本上,你的问题目前无法回答——你给出的例子不具有代表性,而且在你试图做的事情中有太多的未知数。如果你能提供更多的背景,这将非常有帮助。如果您事先知道
i
的类型,那么
t
在哪里出现?如果
t
是除
int
以外的任何类型,那就没有意义了,是吗?当然t可以是任何类型。更重要的是,对我来说,它将是手工制作的类型,而不是原生的.net类型。更重要的是,我本身应该是手工制作的类型,所以如果您试图分配一个
int
变量,但是
t
MyCustomType
,那么您希望如何处理转换?这正是我需要的转换示例。在我的例子中,我是父类,我需要分配子类的值,在编译过程中我不知道,您希望调用什么代码来执行转换?基本上,您的问题目前无法回答-您给出的示例不具有代表性,并且您尝试执行的操作中有太多未知项。CreateNeedChildPacket返回对象类型,而不是子类对象您可以将返回的对象强制转换为BasePacket。CreateNeedChildPacket返回对象类型,不是子类对象您可以将返回的对象强制转换为BasePacket。您的答案很好,但不适合我的情况。因为我一开始就把每个人都搞糊涂了。它可以用来转换为int(IConvertible.ToInt32),但不能转换为BasePacket:(您的答案很好,但不是f