0

例如,我有这个:

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?
4

2 回答 2

4

Convert.ChangeType可以处理范围广泛的类型转换场景,包括这个,非常有效,受制于以下几点:

读者必须了解 Convert.ChangeType() 仅适用于某些标准的 .NET 系统类型。它不适用于任何未实现 IConvertible 的组件,也不适用于自定义类型。

float f = 1.1f;
int i;
Type t = typeof(int);
i = (int)Convert.ChangeType(f, t);
Console.WriteLine(i);

请注意,在您的具体示例中,两种值类型之间的转换ChangeType不会像直接转换那样有效,因为它ChangeType返回装箱为对象的整数值。

如果它们实现,您可以ChangeType与您自己的类一起使用IConvertable,例如

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);
于 2012-06-25T05:45:31.863 回答
1

在您的示例中,您正在创建两个派生类之一并将其存储在一个基变量中......这根本不需要任何强制转换,因为根据继承法则执行此操作非常好。基类型变量总是可以分配一个更派生的对象,因为基类能够做到的任何事情都保证派生类也可以做到,所以它是安全的。例如,数学老师可以执行普通老师可以执行的任何操作(例如 GradePapers())。用 Teacher 变量指向 Math Teacher 对象是安全的。

BasePacket bp = (BasePacket) CreateNeededChildPacket();

编辑: 为了回应您的评论,理想情况下,您应该让 CreateNeededChildPacket() 方法返回 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());
于 2012-06-25T06:27:35.553 回答