如何将对象转换为Type类描述的类型?

时间:2009-07-30 12:01:06

标签: c# .net-3.5 casting types

我有一个对象:

ExampleClass ex = new ExampleClass();

Type TargetType

我想将ex类型转换为TargetType描述的类型:

Object o = (TargetType) ex;

但是当我这样做时,我得到了:

  

类型或命名空间名称't'可以   找不到

那怎么办呢?我在这里遗漏了一些东西吗?

更新

我想获得这样的东西:

public CustomClass MyClassOuter
{
   get
   {
        return (CustomClass) otherClass;
   }
}

private otherClass;

因为我会有很多这样的属性,我想这样做:

public CustomClass MyClassOuter
{
   get
   {
        return (GetThisPropertyType()) otherClass;
   }
}

private SomeOtherTypeClass otherClass;

上下文:

通常在我班级的上下文中,我需要创建许多属性。并且在每一个都取代铸造属性的类型。它对我来说似乎没有意义(在我的上下文中)因为我知道返回类型是什么,我想写一些代码来为我做演员。也许是仿制药的情况,我还不知道。

就像我可以在这个属性中确保我得到正确的对象并且是正确的类型并且100%能够将它转换为属性类型。

所有我需要这样做,以便我不需要在每个属性中指定它必须“将值转换为CustomClass”,我想做一些类似“将值转换为同一个类,因为此属性是”

例如:

class MYBaseClass
{
   protected List<Object> MyInternalObjects;
}

class MyClass
{
   public SpecialClass MyVeryOwnSpecialObject
   {
      get
      {
           return (SpecialClass) MyInteralObjects["MyVeryOwnSpecialObject"];
      }
   }
}

好吧 - 我可以制作上面这样的许多属性 - 但是有两个问题:

1)我需要在MyInternalObjects上指定对象的名称,但它与属性名称相同。我用System.Reflection.MethodBase.GetCurrentMethod()解析了这个名字。

2)在每个属性中,我需要将对象从MyInternalObjects转换为不同的类型。例如,在MyVeryOwnSpecialObject中 - 到SpecialClass。它总是和财产一样。

这就是为什么我想做这样的事情:

class MYBaseClass
{
   protected List<Object> MyInternalObjects;
}

class MyClass
{
   public SpecialClass MyVeryOwnSpecialObject
   {
      get
      {
           return (GetPropertyType()) MyInteralObjects[System.Reflection.MethodBase.GetCurrentMethod().Name];
      }
   }
}

现在担心:好的,为什么?因为在我的应用程序中,我将获得安全类型等所有好处(intellisense)。

第二个:但现在你会在这个地方失去类型安全吗?不。因为我非常确定我的列表中有我的类型的对象。

5 个答案:

答案 0 :(得分:11)

Object o = (TargetType) ex;

这段代码没用。您可能在右侧有一个类型,但它仍然只是左侧的一个对象。您不能像这样使用特定于TargetType的功能。


这是您可以调用给定类型的未知对象的方法:

object myObject = new UnknownType();
Type t = typeof(UnknownType); // myObject.GetType() would also work
MethodInfo sayHelloMethod = t.GetMethod("SayHello");
sayHelloMethod.Invoke(myObject, null);

使用此UnknownType类:

class UnknownType
{
    public void SayHello()
    {
        Console.WriteLine("Hello world.");
    }
}

答案 1 :(得分:3)

通常,这样做的愿望表明存在误解。但是, 非常偶然是合理的理由。这取决于它是否将是引用转换与拆箱或用户定义的转换。

如果是参考转换,则表示实际值(参考)将保持完全不变。所有演员都会执行检查,然后复制该值。这没有用 - 您可以使用Type.IsAssignableFrom代替执行检查,如果您希望将其隐藏在object类型的变量中,则可以使用隐式转换。

强制转换的主要目的是为编译器提供更多信息。现在,如果您只知道执行时的类型,那显然无法帮助编译器。

在您演出后,您计划对object做什么?如果你能解释一下,我们可以尝试解释如何达到你想要的效果。

如果你真的想要进行用户定义的转换或取消装箱转换,那可能是另一回事 - 但我怀疑并非如此。

编辑:看过你的更新后,你的财产被宣布为返回o,所以你只需要:

CustomClass

我怀疑你还没有真正给我们所需的所有信息。是肯定是如何定义您的属性,public CustomClass MyClassOuter { get { return (CustomClass) otherClass; } } 是一个明确的类型?当您知道属性类型时,为什么要尝试动态执行转换?

编辑:听起来你只是想节省一些打字 - 以便更容易剪切和粘贴。别。您在编译时知道类型,因为您在编译时知道属性的类型(它在代码中仅在几行中指定)。直接使用该类型。同样,不要试图获取当前方法的名称来计算要使用的密钥。只需直接输入名称即可。再一次,你在编译时知道它,为什么要动态?当它有意义的时候,我都是懒惰,但在这种情况下,它只是没有。

答案 2 :(得分:1)

现在似乎不可能,但很快就可以在.NET 4.0中使用名为“dynamic”的新功能:

http://www.codeguru.com/vb/vbnet30/article.php/c15645__4/

答案 3 :(得分:1)

我不完全确定你要做什么,但我得到的印象是你想要一个对象的单个实例,它可以“像”许多不同类型的对象一样,并且你想拥有允许你以各种不同的方式很容易地查看这个对象的getter。在这种情况下,我建议制作一个getter方法(不是属性),如下所示:

public T Get<T>()
{
   return (T)myObject;
}

然后你会这样称呼它:

Foo foo = box.Get<Foo>();
Bar bar = box.Get<Bar>();
// etc...

有两点需要注意:这绝对不是类型安全的,因为你可以为T传递任何类型,包括强制转换失败的类型。你可以稍微限制一下,如下:

public T Get<T>() where T : SomeBaseType

如果您尝试使用与SomeBaseType不兼容的类型,会导致编译错误,但我不确定它是否完全可靠。但希望这可以让你在那里大部分时间。

这是你的想法吗?

答案 4 :(得分:0)

if (ex is ExampleClass) 
{
  ExampleClass myObject = (ExampleClass)ex;
}

那会这样做,但我想问题是你想要实现的目标是什么?为什么?我经常发现,如果事情看起来确实存在,真的很难,那么我可能做错了。