【问题标题】:How to cast object to type described by Type class?如何将对象转换为 Type 类描述的类型?
【发布时间】:2010-11-15 10:09:23
【问题描述】:

我有一个对象:

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().Name 解决了这个问题。

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

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

class MYBaseClass
{
   protected List<Object> MyInternalObjects;
}

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

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

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

【问题讨论】:

  • 我已更新我的答案以回应您的编辑。我怀疑我们需要看一个完整的示例才能使这个问题有意义。
  • “它总是与属性相同的类” - 所以将它转换为那个类型!您在编译时就知道该类型;为什么要做其他事情?只是为了省点打字?
  • 如果您开箱即用,您会看到这样做的好处
  • 不,除了让剪切和粘贴更容易之外,我没有看到其他好处。请解释您认为有哪些好处。请注意,如果您只想使用工具生成这些属性,则可以非常轻松地直接使用正确的类型等。
  • (我不是在谈论拥有强类型属性的好处——这很好。我说的是当你实际上静态地知道它时动态查找名称和类型的好处。)

标签: c# .net-3.5 casting types


【解决方案1】:
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.");
    }
}

【讨论】:

  • 我需要强制转换 ex 来键入我的自定义“TargetType”。您打算如何完成这项工作?
  • 您必须通过反射调用方法(或任何您想做的事情)。我会试着找一个例子。
  • 您的上下文代码仍然存在我描述的相同问题。您尝试将某些内容强制转换为 (GetThisPropertyType()) 但最终还是返回了一个 CustomClass 实例。
【解决方案2】:

通常希望这样做表明存在误解。但是, 偶尔会有这样做的正当理由。这取决于它是引用转换还是拆箱或用户定义的转换。

如果是参考转换,这意味着实际值(参考)将完全保持不变。演员所做的只是执行检查,然后复制该值。这没有实际用途 - 您可以改用 Type.IsAssignableFrom 执行检查,如果您希望在 object 类型的变量中使用 object 的隐式转换。

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

完成演员表后,您打算如何处理o?如果你能解释清楚,我们可以试着解释一下如何达到你想要的效果。

如果您真的希望发生用户定义的转换或拆箱转换,那可能是另一回事 - 但我怀疑情况并非如此。

编辑:看到您的更新后,您的财产刚刚宣布返回CustomClass,所以您只需要:

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

我怀疑您还没有真正向我们提供我们需要的所有信息。 肯定你的属性将如何定义,CustomClass 是一个明确的类型?为什么要在知道属性类型的情况下尝试动态执行转换?

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

【讨论】:

  • 我可能错过了这里的重点,但看起来他正在尝试为任何类中的属性制作一个通用的“get”。鉴于这些属性没有命名,我不知道这是如何工作的,但我很高兴在这里接受教育。
  • @Lazarus:这就是我要求提供完整示例的原因。我怀疑当我们看到更多时,会更清楚发生了什么。使用泛型可能会有所帮助,但我们无法从我们所掌握的有限信息中看出这一点。
  • 我需要在不直接指定转换类的情况下进行转换。在属性内部,它知道它是什么类型。我想将 otherClass 转换为此类类型而不直接指定它,因为在这种情况下很明显。
  • 您认为转换为除属性本身类型之外的任何类型的好处在哪里?如果你真的认为你有充分的理由这样做,请发布一个完整的示例。
  • @tomaszs:您不能随意将对象转换为任何类型,它必须是正确的类型或此类继承自的类型。我认为乔恩希望看到一个完整描述的场景,即你为什么需要这样做。目前我们还不清楚,你想要做什么至少对我来说没有多大意义。
【解决方案3】:
if (ex is ExampleClass) 
{
  ExampleClass myObject = (ExampleClass)ex;
}

这样就可以了,但我想问题是你想要达到什么目标,为什么?我经常发现,如果某件事看起来真的,真的很困难,那么我可能做错了。

【讨论】:

  • 只是另一种语法风格,但如果您有多种类类型,您也可以使用类似 here 的 switch 语句。
【解决方案4】:

现在这似乎是不可能的,但很快就会在 .NET 4.0 中提供名为“动态”的新功能:

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

【讨论】:

    【解决方案5】:

    我不完全确定您要做什么,但我得到的印象是您希望拥有某个对象的单个实例,该实例可以“像”许多不同类型的对象一样,并且您希望拥有让您可以非常轻松地以各种不同方式查看这一对象的吸气剂。在这种情况下,我建议制作一个 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 不兼容的类型,这将导致编译错误,但我不确定这是否完全可靠。但希望这能让您顺利完成任务。

    这是你的想法吗?

    【讨论】:

      猜你喜欢
      • 2021-06-26
      • 2012-04-04
      • 1970-01-01
      • 2014-02-11
      • 1970-01-01
      • 2018-11-27
      • 1970-01-01
      • 2017-05-02
      • 1970-01-01
      相关资源
      最近更新 更多