OK,問題的範圍轉移,但我原來的觀察和反對一些其他的解決方案仍然有效。
我認爲你不想在這裏使用'泛型'。您不會提前知道類型,因爲您需要創建類型,所以不需要使用通用實現,因爲MethodBase.Invoke需要一個Object數組。
此代碼假定您正在從數據庫字段實例化目標。如果不是相應調整。
當然這不是全部包含的,也沒有有用的異常處理,但它可以讓你動態地執行任意類型的任意方法,任意類型的參數值都來自一行中的字符串值。
注意:有許多許多情況下,這個簡單的執行程序將無法正常工作。您需要確保您設計動態方法,以配合您最終決定使用的任何策略。
using System;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using NUnit.Framework;
namespace DynamicMethodInvocation
{
[TestFixture]
public class Tests
{
[Test]
public void Test()
{
// from your database
string assemblyQualifiedTypeName = "DynamicMethodInvocation.TestType, DynamicMethodInvocation";
string methodName = "DoSomething";
// this is how you would get the strings to put in your database
string enumString = Executor.ConvertToString(typeof(AttributeTargets), AttributeTargets.Assembly);
string colorString = Executor.ConvertToString(typeof(Color), Color.Red);
string stringString = "Hmm... String?";
object result = Executor.ExecuteMethod(assemblyQualifiedTypeName, methodName,
new[] { enumString, colorString, stringString });
Assert.IsInstanceOf<bool>(result);
Assert.IsTrue((bool)result);
}
}
public class TestType
{
public bool DoSomething(AttributeTargets @enum, Color color, string @string)
{
return true;
}
}
public class Executor
{
public static object ExecuteMethod(string assemblyQualifiedTypeName, string methodName,
string[] parameterValueStrings)
{
Type targetType = Type.GetType(assemblyQualifiedTypeName);
MethodBase method = targetType.GetMethod(methodName);
ParameterInfo[] pInfo = method.GetParameters();
var parameterValues = new object[parameterValueStrings.Length];
for (int i = 0; i < pInfo.Length; i++)
{
parameterValues[i] = ConvertFromString(pInfo[i].ParameterType, parameterValueStrings[i]);
}
// assumes you are instantiating the target from db and that it has a parameterless constructor
// otherwise, if the target is already known to you and instantiated, just use it...
return method.Invoke(Activator.CreateInstance(targetType), parameterValues);
}
public static string ConvertToString(Type type, object val)
{
if (val is string)
{
return (string) val;
}
TypeConverter tc = TypeDescriptor.GetConverter(type);
if (tc == null)
{
throw new Exception(type.Name + " is not convertable to string");
}
return tc.ConvertToString(null, CultureInfo.InvariantCulture, val);
}
public static object ConvertFromString(Type type, string val)
{
TypeConverter tc = TypeDescriptor.GetConverter(type);
if (tc == null)
{
throw new Exception(type.Name + " is not convertable.");
}
if (!tc.IsValid(val))
{
throw new Exception(type.Name + " is not convertable from " + val);
}
return tc.ConvertFrom(null, CultureInfo.InvariantCulture, val);
}
}
}
我認爲你正在尋找的字'動態'而不是'一般'。當您的需求描述需要從描述性字符串動態創建參數值時,您已經獲得了許多有關此用法的解答。我是否正確地理解你? – 2010-03-03 17:15:16
我對所有人回答的其他問題是:在回答之前沒有人完全閱讀和理解問題嗎? Jeez .... – 2010-03-03 17:16:33
好的,下一個問題:你在調用什麼方法?調度方法已知的現有實例化對象,還是您正在實例化目標? – 2010-03-03 17:44:45