РЕДАКТИРОВАНИЕ: Я удалил общую реализацию и очистил этот ответ, чтобы лучше соответствовать первоначально заявленной проблеме.
ПРИМЕЧАНИЕ. Ответ Марка Гравелла, вероятно, является наиболее кратким, если вы просто хотите, чтобы проанализированное значение было задано типом. Ответ ниже показывает, как получить метод (т. Е. Объект MethodInfo и как его вызвать).
Следующее должно работать, по крайней мере, для типов, которые реализуют public static bool TryParse (строка, значение T):
public static class Parsing
{
static MethodInfo findTryParseMethod(Type type)
{
//find member of type with signature 'static public bool TryParse(string, out T)'
BindingFlags access = BindingFlags.Static | BindingFlags.Public;
MemberInfo[] candidates = type.FindMembers(
MemberTypes.Method,
access,
delegate(MemberInfo m, object o_ignored)
{
MethodInfo method = (MethodInfo)m;
if (method.Name != "TryParse") return false;
if (method.ReturnParameter.ParameterType != typeof(bool)) return false;
ParameterInfo[] parms = method.GetParameters();
if (parms.Length != 2) return false;
if (parms[0].ParameterType != typeof(string)) return false;
if (parms[1].ParameterType != type.MakeByRefType()) return false;
if (!parms[1].IsOut) return false;
return true;
}, null);
if (candidates.Length > 1)
{
//change this to your favorite exception or use an assertion
throw new System.Exception(String.Format(
"Found more than one method with signature 'public static bool TryParse(string, out {0})' in type {0}.",
type));
}
if (candidates.Length == 0)
{
//This type does not contain a TryParse method - replace this by your error handling of choice
throw new System.Exception(String.Format(
"Found no method with signature 'public static bool TryParse(string, out {0})' in type {0}.",
type));
}
return (MethodInfo)candidates[0];
}
public static bool TryParse(Type t, string s, out object val)
{
MethodInfo method = findTryParseMethod(t); //can also cache 'method' in a Dictionary<Type, MethodInfo> if desired
object[] oArgs = new object[] { s, null };
bool bRes = (bool)method.Invoke(null, oArgs);
val = oArgs[1];
return bRes;
}
//if you want to use TryParse in a generic syntax:
public static bool TryParseGeneric<T>(string s, out T val)
{
object oVal;
bool bRes = TryParse(typeof(T), s, out oVal);
val = (T)oVal;
return bRes;
}
}
Используйте следующий тестовый код:
public bool test()
{
try
{
object oVal;
bool b = Parsing.TryParse(typeof(int), "123", out oVal);
if (!b) return false;
int x = (int)oVal;
if (x!= 123) return false;
}
catch (System.Exception)
{
return false;
}
try
{
int x;
bool b = Parsing.TryParseGeneric<int>("123", out x);
if (!b) return false;
if (x != 123) return false;
}
catch (System.Exception)
{
return false;
}
try
{
object oVal;
bool b = Parsing.TryParse(typeof(string), "123", out oVal);
//should throw an exception (//no method String.TryParse(string s, out string val)
return false;
}
catch (System.Exception)
{
//should throw an exception
}
return true;
}
}
И используйте это в вашем случае:
//input: string s, Config
Type tNum = Type.GetType(Config.numberType);
object oVal;
bool ok = Parsing.TryParse(tNum, s, out oVal);
//oVal is now of type tNum and its value is properly defined if ok == true
Об использовании var: у вас может быть неправильное представление о том, что делает var: это не «вариантный» тип (объект типа уже используется для этого), но он перемещает синтаксис объявления для типа в правую часть присваивания , Следующие объявления эквивалентны:
var i = 1; //the compiler infers the type from the assignment, type of i is int.
int i = 1; //type of i is int via declaration
Основное использование var позволяет создавать анонимных типов :
var anon = new { Name = "abc", X = 123 };