확인, 질문의 범위는 이동하지만, 일부 다른 솔루션에 내 원래의 관찰과 반대는 여전히 의미합니다.
난 당신이/여기 '제네릭'을 사용할 수 없습니다 생각합니다. 미리 유형을 알지 못하므로 유형을 작성해야하므로 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);
}
}
}
내가 생각 '일반적으로'대신 '동적으로'. 당신은 요구 사항이 설명 문자열에서 매개 변수 값을 동적으로 생성해야하는 필요성을 설명 할 때 그 사용법에 대한 많은 답변을 얻었습니다. 내가 너를 제대로 이해하고 있니? –
내가 대답하는 모든 사람들에게 내 다른 질문은 : 대답하기 전에 질문을 읽고 이해하는 사람은 아무도 없습니까? Jeez .... –
좋아, 다음 질문 : 당신은 무엇을 호출하는거야? 스케줄링 메소드에 알려진 기존의 인스턴스화 된 오브젝트 또는 대상을 인스턴스화하는 중입니까? –