反射类型的default(T)



在浏览其他答案时,我想到了下面的扩展方法,效果很好:

public static T Convert<T>( this string input )
{
    var converter = TypeDescriptor.GetConverter( typeof( T ) );
    if ( converter != null )
    {
        try
        {
            T result = (T) converter.ConvertFromString( input );
            return result;
        }
        catch
        {
            return default( T );
        }
    }
    return default( T );
}

我可以这样使用:

string s = "2011-09-21 17:45";
DateTime result = s.ConvertTo( typeof( DateTime ) );
if ( result == DateTime.MinValue )
    doSomethingWithTheBadData();

太棒了!伟大的工作。现在,我想对反射类型做一些类似的事情。我:

public static dynamic ConvertTo( this string input, Type type )
{
    var converter = TypeDescriptor.GetConverter( type );
    if ( converter != null )
    {
        try
        {
            dynamic result = converter.ConvertFromString( input );
            return ( result );
        }
        catch
        {
            return default( type );  // bogus
        }
    }
    return default( type );  // bogus
}

我想这样使用它:

Type someType;  // will be DateTime, int, etc., but not known until runtime
DateTime result = s.ConvertTo( sometype );
if ( result == DateTime.MinValue )
    doSomethingWithTheBadData();

当然,编译器对ConvertTo方法中的'bogus'行表示反对。我需要的(好吧,不一定需要,但这很好)是一种获得与第一个示例相同结果的方法,以便如果转换失败,可以返回可以分配给反射对象的东西,并且可以以与第一个示例相同的方式进行识别。

编辑:

我完成了什么:

public static dynamic ConvertTo( this string input, Type type, out bool success )
{
    dynamic result;
    var converter = TypeDescriptor.GetConverter( type );
    if ( converter != null )
    {
        try
        {
            result = converter.ConvertFromString( input );
            success = true;
            return result;
        }
        catch { /* swallow the exception */ }
    }
    result = type.IsValueType ? Activator.CreateInstance( type ) : null;
    success = false;
    return result;
}

和使用:

bool success;
string val = "2011-09-21 17:25";
dateTime = val.ConvertTo( typeof( DateTime ), out success );
if ( success )
    doSomethingGood();
val = "foo";
dateTime = val.ConvertTo( typeof( DateTime ), out success );
if ( !success )
    dealWithBadData();
请记住,为了演示,我对typeof()位进行了硬编码。在我的应用程序中,类型都被反映了。

感谢所有人的快速回答!

可以使用

//to get default(T) from an instance of Type
type.IsValueType ? Activator.CreateInstance(type) : null;

这是因为值类型保证有一个默认构造函数,并且引用类型的默认值是null

如果您使用typeof(Type)传递类型,那么显然您可以使用第一个方法。然后,假设您通过反射(您说您是)获得类型,那么您也可以使用反射来获得MethodInfo为您的第一个版本的Convert(),然后使用MakeGenericMethod()将您的反射类型替换为它:

MethodInfo m = typeof(MyConvertExtensions).GetMethod("Convert");
MethodInfo invocable = m.MakeGenericMethod(myReflectedType);
invocable.Invoke(null, new[] { myString });

未经测试,但也许是这样的?

public static dynamic ConvertTo(this string input, Type type)
{
    var converter = TypeDescriptor.GetConverter(type);
    if (converter != null)
    {
        try
        {
            return converter.ConvertFromString(input);
        }
        catch
        {
            // ignore
        }
    }
    if (type.IsValueType)
        return Activator.CreateInstance(type);
    return null;
}

相关内容

  • 没有找到相关文章

最新更新