[英]Dynamically calling method and class name
我有一些情況需要從類名調用方法名稱。
string scenario1 = "MockScenario1";
string scenario2 = "MockScenario2";
MockScenario1.GetInfo();
MockScenario2.GetInfo();
如何在這里動態使用字符串來調用方法名稱
scenario1.GetInfo()
scenario2.GetInfo()
我試圖通過字符串和控制空間找出所有選項來查找相關選項。 有什么建議?
我嘗試了以下嘗試動態生成類名
下面的代碼動態生成方法名稱
string methodName = "hello";
//Get the method information using the method info class
MethodInfo mi = this.GetType().GetMethod(methodName);
//Invoke the method
// (null- no parameter for the method call
// or you can pass the array of parameters...)
mi.Invoke(this, null);
更明確的場景:我試圖發送類名作為參數MockScenario1和MockScenario2是類名。
string scenarioCats = "MockScenario1";
string scenarioDogs = "MockScenario2";
GetResult(scenarioCats);
GetResult(scenarioDogs);
public static void GetCatsResult(string scenarioCats){
scenarioCats obj = new scenarioCats();
obj.GetInfo();
}
public static void GetDogsResult(string scenarioDogs){
scenarioDogs obj = new scenarioDogs();
obj.GetInfo();
}
如何從字符串表示形式創建類型的實例:
string scenario1 = "TheNamespace.MockScenario1";
Type theType = this.GetType().Assembly.GetType(scenario1);
var theInstance = (MockScenario1)Activator.CreateInstance(theType);
theInstance.GetInfo();
如果你的類實現了一個通用接口,例如IGetInfoAware ,那么你可以寫一個更通用的加載器:
var theInstance = (IGetInfoAware)Activator.CreateInstance(theType);
注意:您需要為scenario1和scenario2提供完整的類名
編輯:
正如@Georg指出的那樣,如果類型沒有在上下文對象的程序集中聲明,那么首先需要獲取托管類型的程序集:
var theAssembly = (
from Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()
where (assembly.FullName == "TheNamespace.AssemblyName")
select assembly
)
.FirstOrDefault();
if ( theAssembly!= null ){
Type theType = theAssembly.GetType(scenario1);
var theInstance = (IGetInfoAware)Activator.CreateInstance(theType);
theInstance.GetInfo();
}
如果由於某種原因您不知道程序集名稱,則可以解析類型如下:
public Type GetTypeFromString(String typeName)
{
foreach (Assembly theAssembly in AppDomain.CurrentDomain.GetAssemblies())
{
Type theType = theAssembly.GetType(typeName);
if (theType != null)
{
return theType;
}
}
return null;
}
你可以使用反射:
Type thisType = this.GetType();
MethodInfo theMethod = thisType.GetMethod(FunctionName);
theMethod.Invoke(this, userParameters);
您可以使用命令設計模式。 因此,您將使用哈希映射將字符串存儲為哈希映射中的鍵,然后您的函數將是哈希映射的值。 然后,當你想調用你的函數時,你會說hashmap.get(“yourString”)。 這將返回您存儲為值的函數,您可以從那里調用它。
我建議使用Dictionary<String, Action>
,你可以放下所有場景及其名稱,例如
private static Dictionary<String, Action> s_Scenario =
new Dictionary<String, Action>() {
{"MockScenario1", () => MockScenario1.GetInfo()},
{"MockScenario2", () => MockScenario2.GetInfo()},
};
...
s_Scenario["MockScenario1"]();
s_Scenario["MockScenario2"]();
沒有給Namespace
提供GetType()
總是可以返回null(我在添加這個答案之前遇到了這個問題。),所以它應該是這樣的;
如您所述,您希望將string作為參數
public void GetCatsResult(string scenarioCats)
{
string item = this.GetType().Namespace + "." + scenarioCats;
// combined class string with the namespace
Type className = Type.GetType(item);
// found the class
MethodInfo m = className.GetMethod("GetInfo");
// get the method from class
object value = m.Invoke(null,null);
// invoke and value will represent the return value.
}
這是我的Scenario類,
class Scenario1
{
public static string GetInfo()
{
return "GetInfo() called, Scenario1";
}
}
結果; (btw在Form_Load
調用GetCatsResult()
並給出聲明為string scenario1 = "Scenario1";
)
希望有幫助,
如果是用於測試,您可以使用PrivateObject:
using Microsoft.VisualStudio.TestTools.UnitTesting;
class Class1
{
public Class1()
{
MyClass myClass = new MyClass();
PrivateObject myClassPrivateObject = new PrivateObject(myClass, new PrivateType(typeof(MyClass)));
myClassPrivateObject.Invoke("MyMethod");
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.