簡體   English   中英

動態調用方法和類名

[英]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提供完整的類名

請參閱Activator.CreateInstance

編輯:

正如@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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM