2011-09-21 113 views
1

我正在實現一個Web控件,它使用特定函數獲取對象(作爲參數) - 我們稱之爲DoStuff() - 對象可以屬於不同的類,這些都是派生自一個抽象類 - 讓我們稱之爲SuperClass - 這個SuperClass沒有DoStuff()方法。執行未開發對象的函數

所以我的問題是:是否有一種方法在C#中調用運行時的對象的方法,如果此方法存在於對象中,而不必將其轉換爲派生類。

喜歡的東西(我知道這不工作,但我認爲它表達更好,我想什麼來完成):

if(myObject.Functions["DoStuff"] != null){ 
    myObject.executeFunction("DoStuff"); 
} 

這是在所有可能的?

+0

是對象保證有法? – BoltClock

+0

@BoltClock是的,控件只能在類有方法時調用。 – woolagaroo

回答

3

這可能與反思,如:

uses System.Reflection 

.... 

public void ExecuteMethod(object thing, string method) 
{ 
    Type type = thing.GetType(); //gets the runtime type of the object 
    MethodInfo mi = type.GetMethod(method); // null if method not found 
    mi.Invoke(thing, null); //invokes the method on the "thing" object, 
          //passing null arguments, and returns the result 

} 

但是,在你的場景中,創建一個接口IDoStuff將會更好(如果可能),該接口將有DoStuff方法,並使所有可能調用的類實現它。
這樣,你的代碼會更簡單,更容易出錯,就像這樣:

public void ExecuteDoStuff(object thingy) 
{ 
    if (thingy is IDoStuff) 
     ((IDoStuff)thingy).DoStuff(); 
    else 
     throw new Exception("thingy cannot do stuff"); 
} 
+0

我也喜歡界面解決方案,但是這是不可能的,因爲我只是提供控制...所以反射是激動人心的,我一直在尋找;) – woolagaroo

2

那麼,在C#4你可以寫:

dynamic d = myObject; 
d.DoStuff(); 

這將拋出一個異常,如果DoStuff()方法不能綁定,但是綁定僅在執行時檢查

這是相對棘手找出是否這回事不只是在做它的工作 - 你總是可以趕上課程的例外,但它的效果並不理想。

你可以嘗試用反射來找到它,但我不認爲這是一個想法的方法。

更大的問題是爲什麼抽象類沒有DoStuff方法,至少作爲一個抽象方法。那將是一個更好的解決方案。

如果只有子類的一些DoStuff方法,這將是更好地將它放入一個接口:

​​

然後做出相應的子類實現IStuffable,你可以寫:

IStuffable stuffable = myObject as IStuffable; 
if (stuffable != null) 
{ 
    stuffable.DoStuff(); 
} 
1

有幾種方法可以做到這一點。我開始與那些推薦:

  • 創建界面至極包含您DoStuff()方法的所有的類都實現了。然後投你的對象是接口:

    interface IDoStuff { 
        void DoStuff(); 
    } 
    
    // call it on your object 
    ((IDoStuff)object).DoStuff(); 
    
  • 擴展您的基類來包含DoStuff()方法(如果可能)

  • 使用反射來調用方法:

    object.GetType().GetMethod("DoStuff").Invoke();