Отражение статического перегруженного метода с использованием параметра out
У меня возникли проблемы с вызовом перегруженного статического метода с параметром out через отражение и были бы оценены некоторые указатели.
Я хочу динамически создавать тип типа System.Int32
или System.Decimal
, а затем вызывать на нем статический метод TryParse(string, out x)
.
В приведенном ниже коде есть две проблемы:
-
t.GetMethod("TryParse", new Type[] { typeof(string), t } )
не возвращает возвращаемый метод MethodInfo
-
mi.Invoke(null, new object[] { value.ToString(), concreteInstance })
кажется успешным, но не устанавливает параметр out concreteInstance
в анализируемое значение
Взаимодействуя с этой функцией, вы можете увидеть временный код, демонстрирующий, что должно произойти, если параметр type
был установлен на System.Decimal
.
public static object Cast(object value, string type)
{
Type t = Type.GetType(type);
if (t != null)
{
object concreteInstance = Activator.CreateInstance(t);
decimal tempInstance = 0;
List<MethodInfo> l = new List<MethodInfo>(t.GetMethods(BindingFlags.Static | BindingFlags.Public));
MethodInfo mi;
mi = t.GetMethod("TryParse", new Type[] { typeof(string), t } ); //this FAILS to get the method, returns null
mi = l.FirstOrDefault(x => x.Name == "TryParse" && x.GetParameters().Length == 2); //ugly hack required because the previous line failed
if (mi != null)
{
try
{
bool retVal = decimal.TryParse(value.ToString(), out tempInstance);
Console.WriteLine(retVal.ToString()); //retVal is true, tempInstance is correctly set
object z = mi.Invoke(null, new object[] { value.ToString(), concreteInstance });
Console.WriteLine(z.ToString()); //z is true, but concreteInstance is NOT set
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
return concreteInstance;
}
return value;
}
Что мне нужно сделать, чтобы мой вызов t.GetMethod()
возвращал правильный MethodInfo? Что мне нужно сделать, чтобы concreteInstance
правильно установить в моем вызове mi.Invoke()
?
Я знаю, что есть несколько вопросов по этой теме, но большинство из них связаны с статическими универсальными методами или статическими методами, которые не перегружены. Этот вопрос похож, но не дублируется.
Ответы
Ответ 1
Вам нужно использовать правильный BindingFlags
и использовать параметры Type.MakeByRefType
для out
и ref
. Одна секунда, и у меня будет образец кода для вас.
Например,
MethodInfo methodInfo = typeof(int).GetMethod(
"TryParse",
BindingFlags.Public | BindingFlags.Static,
Type.DefaultBinder,
new[] { typeof(string), typeof(int).MakeByRefType() },
null
);
Я должен указать, что ссылаться на это немного сложно. Вот как вы это делаете.
string s = "123";
var inputParameters = new object[] { "123", null };
methodInfo.Invoke(null, inputParameters);
Console.WriteLine((int)inputParameters[1]);
Первый null
заключается в том, что мы вызываем статический метод (нет объекта, "получающего" этот вызов). null
в inputParameters
будет "заполнен" для нас с помощью TryParse
с результатом анализа (это параметр out
).