簡體   English   中英

反射類型的默認值(T)

[英]default(T) on reflected type

在瀏覽其他答案時,我想出了以下擴展方法:

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)傳入typeof(Type) ,那么顯然你可以使用第一種方法。 那么,假設您通過反射獲得了類型(您說你是),那么您也可以使用反射來獲取第一個版本的Convert()MethodInfo ,然后使用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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM