2012-09-02 23 views
71

如果我有:如何將Object轉換爲其實際類型?

void MyMethod(Object obj) { ... } 

我怎麼能投obj其實際類型是什麼?

+2

該類型在編譯時是否已知? – psubsee2003

+1

你期望從這方面完成什麼?請告訴我們你想達到的目標,而不是你期望達到的目標。 –

+0

@JonSkeet:我希望能夠從對象中調用一個函數。目前'obj.MyFunction();'不能編譯,即使我知道真實的對象確實有這個功能。 –

回答

117

如果你知道實際的類型,然後只是:

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

什麼是Swift中的等效語法? – Rao

+1

Nevermind,發現'as'爲類型轉換和'type(of:ClassName)'函數來檢查實例類型。 – Rao

0

鑄造實際類型很容易:

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

這很有趣... – Steve

+1

這是不合邏輯的。你實際上不知道實際的類型。你應該怎麼做? –

28

我不認爲你可以(不是沒有反思),你應該爲你的功能提供一個類型:

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

這真的是一個無用的答案,不配得票。按照OP的要求,反射類型對象的對象不會產生對象的「實際類型」。另外,你的MyMethod邏輯是有缺陷的,因爲obj可以是A類型的,也可以是B類型的。你的邏輯沒有提供「實際類型」(如OP所要求的) - 它提供了兼容類型,並不一定在那個期望的類型。 – Jazimov

0
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); 
} 
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

在我的情況下,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

相關問題