简体   繁体   English

反射类型的默认值(T)

[英]default(T) on reflected type

In browsing other answers, I have come up with the following extension method which works a treat: 在浏览其他答案时,我想出了以下扩展方法:

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 );
}

And I can use it like: 我可以像以下一样使用它:

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

Awesome! 真棒! Works great. 效果很好。 Now, I'd like to do something similar with a reflected type. 现在,我想用反射类型做类似的事情。 I have: 我有:

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
}

And I'd like to use it thus: 我想这样使用它:

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

Of course, the compiler objects to the 'bogus' lines in the ConvertTo method. 当然,编译器会对ConvertTo方法中的'bogus'行进行反对。 What I need (ok, don't necessarily need , but it'd be nice) is a way to get the same result as in the first example so that if the conversion fails, something that can be assigned to the reflected object is returned and can be recognized in the same manner as in the first example. 我需要的东西(好吧,不一定需要 ,但它很好)是一种获得与第一个例子相同结果的方法,这样如果转换失败,可以返回可以分配给反射对象的东西并且可以以与第一示例中相同的方式识别。

Edit: 编辑:

What I finished with: 我完成了什么:

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;
}

and used: 和使用:

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();

Remembering that, for the purpose of demonstration, I'm hard-coding the typeof() bit. 记住,为了演示,我很难对typeof()位进行编码。 In my application, the types are all reflected. 在我的应用程序中,所有类型都反映出来。

Thanks to all for the speedy answers! 感谢所有人的快速回答!

You can use 您可以使用

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

This is because value types are guaranteed to have a default constructor, and the default value of a reference type is a null . 这是因为值类型保证具有默认构造函数,并且引用类型的默认值为null

If you're passing in the type using typeof(Type) , then obviously you could just use the first method. 如果你使用typeof(Type)传入typeof(Type) ,那么显然你可以使用第一种方法。 Assuming, then, that you're getting the type via reflection (which you say you are) then you can also use reflection to get the MethodInfo for your first version of Convert() , and then use MakeGenericMethod() to substitute your reflected type into it: 那么,假设您通过反射获得了类型(您说你是),那么您也可以使用反射来获取第一个版本的Convert()MethodInfo ,然后使用MakeGenericMethod()替换您的反射类型进去:

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

Untested, but maybe something like this? 未经测试,但可能是这样的?

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM