C# 如何动态调用TryParse?

C# 如何动态调用TryParse?,c#,.net,type-conversion,C#,.net,Type Conversion,有没有办法动态调用TryParse?某种程度上: public static bool TryParse<T>(string toConvert, out T result) publicstaticbooltryparse(字符串转换,输出结果) 当然,我们可以使用类型转换器来实现这一点。但是,无效的转换将导致异常,我想消除它。您可以编写如下内容: public delegate bool TryParser<T>(string input, out T resul

有没有办法动态调用
TryParse
?某种程度上:

public static bool TryParse<T>(string toConvert, out T result)
publicstaticbooltryparse(字符串转换,输出结果)

当然,我们可以使用类型转换器来实现这一点。但是,无效的转换将导致异常,我想消除它。

您可以编写如下内容:

public delegate bool TryParser<T>(string input, out T result);

public static bool TryParse<T>
     (string toConvert, out T result, TryParser<T> tryParser = null)
{
    if (toConvert == null)
        throw new ArgumentNullException("toConvert");

    // This whole block is only if you really need
    // it to work in a truly dynamic way. You can additionally consider 
    // memoizing the default try-parser on a per-type basis.
    if (tryParser == null)
    {
        var method = typeof(T).GetMethod
                 ("TryParse", new[] { typeof(string), typeof(T).MakeByRefType() });

        if (method == null)
            throw new InvalidOperationException("Type does not have a built in try-parser.");

        tryParser = (TryParser<T>)Delegate.CreateDelegate
            (typeof(TryParser<T>), method);
    }

    return tryParser(toConvert, out result);
}

我真的不建议这样做,除非您有一些场景需要它。

您可以使用反射动态调用
TryParse
方法。这样,如果转换失败,就不会出现耗时的异常

此方法是此方法的稍微优化版本

//尝试使用反射进行解析
公共静态bool TryConvertValue(字符串stringValue,out T convertedValue)
{
var targetType=typeof(T);
if(targetType==typeof(string))
{
convertedValue=(T)Convert.ChangeType(stringValue,typeof(T));
返回true;
}
var nullableType=targetType.IsGenericType&&
targetType.GetGenericTypeDefinition()==typeof(可为空);
if(nullableType)
{
if(string.IsNullOrEmpty(stringValue))
{
convertedValue=默认值(T);
返回true;
}
targetType=新的NullableConverter(targetType).UnderlinedType;
}
类型[]argTypes={typeof(string),targetType.MakeByRefType()};
var tryParseMethodInfo=targetType.GetMethod(“TryParse”,argTypes);
if(tryParseMethodInfo==null)
{
convertedValue=默认值(T);
返回false;
}
对象[]args={stringValue,null};
var successfulParse=(bool)tryParseMethodInfo.Invoke(null,args);
如果(!successfulParse)
{
convertedValue=默认值(T);
返回false;
}
convertedValue=(T)参数[1];
返回true;
}

也许您可以使用System.Reflection中的某些内容。我没有用反射处理泛型,但它可能会像get type info一样,查看
TryParse()
是否存在,如果存在,
Invoke()
,否则返回false。相关:特别是查看添加并将结果复制回。很好。建议:在
if(nullableType)
块中,当您检查
stringValue
中的
null
时,可能应该改为说
string.IsNullOrEmpty(stringValue)
。我这样认为的原因是
Nullable.ToString()
HasValue
为false时返回
”。因此空字符串可能被认为是有效的字符串表示形式,例如
(int?.null
。感谢您的输入。但是,如果使用“”调用此方法以转换可为null的值,则输出值将为null,返回值将为false。这是正确的,因为“”不应是解析int?的有效值?。如果我使用string.IsNullOrEmpty,返回值将为true,这对imho来说是不正确的。这完全可以。但这意味着
可空的
将不会“往返”。假设您有:
int?i=零;字符串s=i.ToString();智力?tmp;bool canParse=TryConvertValue(s,out tmp)。然后,
canParse
将为false,即使字符串
s
直接来自
int?
ToString
调用。另请参见。另一个问题:
out
参数
convertedValue
的类型应为
T
,而不是
object
。那些台词帮助了我。谢谢类型[]argTypes={typeof(string),targetType.MakeByRefType()};var tryParseMethodInfo=targetType.GetMethod(“TryParse”,argTypes);这是一个惊人的发现。非常感谢。
int result;
bool success = TryParse("123", out result);
    //Try Parse using Reflection
public static bool TryConvertValue<T>(string stringValue, out T convertedValue)
{
    var targetType = typeof(T);
    if (targetType == typeof(string))
    {
        convertedValue = (T)Convert.ChangeType(stringValue, typeof(T));
        return true;
    }
        var nullableType = targetType.IsGenericType &&
                       targetType.GetGenericTypeDefinition() == typeof (Nullable<>);
    if (nullableType)
    {
        if (string.IsNullOrEmpty(stringValue))
        {
            convertedValue = default(T);
            return true;
        }
            targetType = new NullableConverter(targetType).UnderlyingType;
    }

    Type[] argTypes = { typeof(string), targetType.MakeByRefType() };
    var tryParseMethodInfo = targetType.GetMethod("TryParse", argTypes);
    if (tryParseMethodInfo == null)
    {
        convertedValue = default(T);
        return false;
    }

    object[] args = { stringValue, null };
    var successfulParse = (bool)tryParseMethodInfo.Invoke(null, args);
    if (!successfulParse)
    {
        convertedValue = default(T);
        return false;
    }

    convertedValue = (T)args[1];
    return true;
}