2011-12-19 38 views
0

沒有參數我有一個方法:調用的公共方法,在我的用戶控制使用反射

public string ControleIdContainer() 
{ 
    string abc = "Hello"; 
    return abc; 
} 

現在我想調用這個方法在使用反射我的網頁。我曾經試過,但它不工作:

DirectoryInfo dirInfo = new DirectoryInfo(Server.MapPath("~/UserControls")); 
FileInfo[] controlsInfo = dirInfo.GetFiles("*.ascx"); 
foreach (var item in controlsInfo) 
{ 
    var customControl = LoadControl(string.Format("~/UserControls/{0}", item)); 
    var controlType = customControl.GetType(); 
    var controlClientScript = controlType.GetMethod("ControleIdContainer").Invoke(null,null); 
} 
+0

也許你應該使用一個接口,比如'IHaveControleIdContainer' - 那麼你可以做一個'as'投,測試空,並調用該方法。 – 2011-12-19 18:42:32

+0

回聲@ default.kramer ...是的,總是避免反射,只要你可以。這應該是最後的手段。 – bobbymcr 2011-12-19 19:06:29

回答

1

MethodInfo.Invoke第一個參數是要調用的方法的實例。通過customControl作爲第一個參數而不是null,它應該工作。

+0

它的工作,但你可以看到我在循環中調用它,所以下次它給了我錯誤「對象引用未設置爲對象的實例」 – 2011-12-19 18:35:23

+0

@HaseebKhan:這可能是由於各種原因。 'customControl'爲空嗎? 'GetMethod'返回一個空'MethodInfo'?嘗試在該代碼中添加一些針對'null'的檢查來縮小問題的位置。 – bobbymcr 2011-12-19 18:38:35

+0

謝謝親愛的,非常感謝 – 2011-12-19 18:43:49

1

有很多原因讓錯誤

1原因1

您還沒有給出Invoke內的類實例作爲第一個參數。該代碼應該是

var controlClientScript = controlType.GetMethod("MethodName").Invoke(classInstance,null); 

。原因2

可以有多種方法,用你的方法(重載方法)的名稱相同。在這種情況下,它會顯示下面的錯誤。

發生未處理的 類型異常'System.Reflection.AmbiguousMatchException'。模糊匹配 找到。

所以你需要指定你正在調用沒有參數的方法。使用下面的代碼。

MethodInfo mInfo = classInstance.GetType().GetMethods().FirstOrDefault 
       (method => method.Name == "MethodName" 
       && method.GetParameters().Count() == 0); 
mInfo.Invoke(classInstance, null); 

3.原因3

如果使用Type.GetType獲得類的類型,如果類是另一個組件,Type.GetType將是無效的。在這種情況下,您可以通過Assemblies進行循環。使用下面的代碼。

Type type = GetTheType("MyNameSpace.MyClass"); 
object objMyClass = Activator.CreateInstance(type); 
MethodInfo mInfo = ojMyClass.GetType().GetMethods().FirstOrDefault 
        (method => method.Name == "MethodName" 
        && method.GetParameters().Count() == 0); 
mInfo.Invoke(objMyClass, null); 

GetTheType方法就在這裏。到GetTheType參數必須是一個Fully Qualified Name

public object GetTheType(string strFullyQualifiedName) 
{ 
     Type type = Type.GetType(strFullyQualifiedName); 
     if (type != null) 
      return Activator.CreateInstance(type); 
     foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) 
     { 
      type = asm.GetType(strFullyQualifiedName); 
      if (type != null) 
       return Activator.CreateInstance(type); 
     } 
     return null; 
}