如何将Object转换为其实际类型?


120

如果我有:

void MyMethod(Object obj) {   ...   }

如何obj转换为实际类型?


2
在编译时是否知道类型?
psubsee2003

1
您希望从中完成什么?请告诉我们您要达到的目标,而不是期望达到的目标。
乔恩·斯基特

@JonSkeet:我希望能够从对象中调用函数。obj.MyFunction();即使我知道真实对象确实具有该功能,当前也无法编译。
Paul Lassiter

@ psubsee2003:不,不是,因为它是通过互操作传递的对象引用。
Paul Lassiter

3
@PaulLassiter:如果您不知道类型,该声明什么MyFunction方法?
乔恩·斯基特

Answers:


195

如果您知道实际的类型,则只需:

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();

1
Swift中的等效语法是什么?
Nagendra Rao

1
没关系,可as用于类型转换和type(of: ClassName)检查实例类型的功能。
Nagendra Rao

42

我认为您可以(并非没有反思),也应该为您的函数提供一种类型:

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;
        ...
    }
}

4
这确实是一个无用的答案,不值得投票。如OP所要求的,对类型为object的对象的反射不会产生该对象的“实际类型”。另外,您的MyMethod逻辑有缺陷,因为obj可以是A类型,也可以是B类型。您的逻辑不提供“实际类型”(按OP的要求),它提供兼容的类型,不一定所需的类型。
Jazimov '18

使用obj.GetType()。那肯定会返回它的实际类型。
JSON

3

怎么样JsonConvert.DeserializeObject(object.ToString());


这不是令人满意的答案。OP的问题与Json或序列化无关。

@ user12637955这实际上是一个有效的答案,但是由于装箱和拆箱,例如,对象-> ToString()->具体类型,具有更大的复杂性。为了更准确,它应如下所示:var myType = JsonConvert.DeserializeObject<MyType>(object.ToString());
可口可乐

1

就我而言,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


0

如果您的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();
}

0

如果现在将其强制转换为真实类型,例如,它是从名为abc的类定向的。您可以通过以下方式调用函数:

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

如果您不知道该功能,可以用其他方法完成。总是不容易。但是您可以通过其签名以某种方式找到它。如果是这种情况,您应该告诉我们。


0

这种方法可能不是最有效的,但是很简单并且可以完成工作。

它执行两个操作:首先,它调用.ToString(),它基本上是一个序列化,然后使用Newtonsoft nuget(必须安装)进行反序列化。

public T Format<T>(Object obj) =>
    JsonConvert.DeserializeObject<T>(obj.ToString());

您应该为将来的读者简要描述您的答案。
Suraj Kumar

-1

转换为实际类型很容易:

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

8
这是不合逻辑的。您实际上不知道实际的类型。你应该怎么做?
艾伦·利纳托茨

-2
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 );
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.