【问题标题】:How to cast Object to its actual type?如何将 Object 转换为其实际类型?
【发布时间】:2012-08-27 09:05:03
【问题描述】:

如果我有:

void MyMethod(Object obj) {   ...   }

如何将obj 转换为它的实际类型?

【问题讨论】:

  • 在编译时类型是否已知?
  • 您希望从中获得什么?请告诉我们您想要实现的目标,而不是您希望如何实现。
  • @JonSkeet:我希望能够从对象调用函数。目前obj.MyFunction(); 无法编译,即使我知道真实对象确实具有该功能。
  • @PaulLassiter:如果你不知道类型,什么声明了MyFunction 方法?
  • 如果你想在这个对象上调用一个方法,为什么不实现一个接口并在你的方法 MyMethod(IMyinterface obj) 中调用它?

标签: c# object types casting typeof


【解决方案1】:

如果您知道实际类型,那么只需:

SomeType typed = (SomeType)obj;
typed.MyFunction();

如果你不知道实际的类型,那么:不是真的,不。您必须改用以下之一:

  • 反思
  • 实现一个众所周知的接口
  • 动态

例如:

// reflection
obj.GetType().GetMethod("MyFunction").Invoke(obj, null);

// interface
IFoo foo = (IFoo)obj; // where SomeType : IFoo and IFoo declares MyFunction
foo.MyFunction();

// dynamic
dynamic d = obj;
d.MyFunction();

【讨论】:

  • Swift 中的等价语法是什么?
  • 没关系,找到as 用于类型转换和type(of: ClassName) 函数用于检查实例类型。
【解决方案2】:

我认为你不能(不是没有反射),你也应该为你的函数提供一个类型:

void MyMethod(Object obj, Type t)
{
    var convertedObject = Convert.ChangeType(obj, t);
    ...
}

UPD

这可能对你有用:

void MyMethod(Object obj)
{
    if (obj is A)
    {
        A a = obj as A;
        ...
    } 
    else if (obj is B)
    {
        B b = obj as B;
        ...
    }
}

【讨论】:

  • 对象类型对象的反射不会产生对象的“实际类型”,正如 OP 所要求的那样。此外,您的 MyMethod 逻辑存在缺陷,因为 obj 可以是 A 类型,也可以是 B 类型。您的逻辑不提供“实际类型”(按照 OP 的要求)——它提供了兼容的类型,但不一定所需的类型。
  • 使用 obj.GetType()。那肯定会返回它的实际类型。
  • 我们已经知道“类型”。他希望它像“T”一样解决
【解决方案3】:

怎么样

JsonConvert.DeserializeObject<SomeType>(object.ToString());

【讨论】:

  • @user12637955 这实际上是一个可行的答案,但由于装箱和拆箱,即 object -> ToString() -> 到具体类型,它具有更大的复杂性。更准确地说,它应该如下所示:var myType = JsonConvert.DeserializeObject&lt;MyType&gt;(object.ToString());
【解决方案4】:

如果您的MyFunction() 方法仅在一个类(及其后代)中定义,请尝试

void MyMethod(Object obj) 
{
    var o = obj as MyClass;
    if (o != null)
        o.MyFunction();
}

如果你有大量不相关的类定义你要调用的函数,你应该定义一个接口并让你的类定义那个接口:

interface IMyInterface
{
    void MyFunction();
}

void MyMethod(Object obj) 
{
    var o = obj as IMyInterface;
    if (o != null)
        o.MyFunction();
}

【讨论】:

    【解决方案5】:

    就我而言,AutoMapper 运行良好。

    AutoMapper 无需任何显式配置即可映射到动态对象/从动态对象映射:

    public class Foo {
        public int Bar { get; set; }
        public int Baz { get; set; }
    }
    dynamic foo = new MyDynamicObject();
    foo.Bar = 5;
    foo.Baz = 6;
    
    Mapper.Initialize(cfg => {});
    
    var result = Mapper.Map<Foo>(foo);
    result.Bar.ShouldEqual(5);
    result.Baz.ShouldEqual(6);
    
    dynamic foo2 = Mapper.Map<MyDynamicObject>(result);
    foo2.Bar.ShouldEqual(5);
    foo2.Baz.ShouldEqual(6);
    

    同样,您可以直接从字典映射到对象,AutoMapper 会将键与属性名称对齐。

    更多信息https://github.com/AutoMapper/AutoMapper/wiki/Dynamic-and-ExpandoObject-Mapping

    【讨论】:

      【解决方案6】:

      如果你现在的类型是从名为 abc 的类定向的,则将它转换为它的真实类型。 你可以这样调用你的函数:

      (abc)(obj)).MyFunction();
      

      如果您不知道该功能,可以用不同的方式完成。总是不容易。但是你可以通过它的签名以某种方式找到它。如果您遇到这种情况,请告知我们。

      【讨论】:

        【解决方案7】:

        如果可能有多种类型,方法本身不知道要转换的类型,但调用者知道,你可能会使用这样的东西:

        void TheObliviousHelperMethod<T>(object obj) {
            (T)obj.ThatClassMethodYouWantedToInvoke();
        }
        
        // Meanwhile, where the method is called:
        TheObliviousHelperMethod<ActualType>(obj);
        

        可以在括号后使用where 关键字添加对类型的限制。

        【讨论】:

          【解决方案8】:
          Implement an interface to call your function in your method
          interface IMyInterface
          {
           void MyinterfaceMethod();
          }
          
          IMyInterface MyObj = obj as IMyInterface;
          if ( MyObj != null)
          {
          MyMethod(IMyInterface MyObj );
          }
          

          【讨论】:

            【解决方案9】:

            转换为实际类型很容易:

            void MyMethod(Object obj) {
                ActualType actualyType = (ActualType)obj;
            }
            

            【讨论】:

            • 这不合逻辑。你实际上不知道实际的类型。你应该怎么做?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-20
            • 2018-11-12
            • 1970-01-01
            • 1970-01-01
            • 2020-04-06
            相关资源
            最近更新 更多