Reflection a generický datový typ

Tomáš Holan       18. 12. 2012       Reflexe       5122 zobrazení

V článku zde obsahovala třída ExceptionExtensions tuto pomocnou metodu:

private static System.ServiceModel.ExceptionDetail TryGetExceptionDetail(Exception ex)
{
    if (!(ex is System.ServiceModel.FaultException))
    {
        return null;
    }

    Type exceptionType = ex.GetType();
    while (exceptionType != null)
    {
        if (exceptionType.IsGenericType && exceptionType.GetGenericTypeDefinition() == typeof(System.ServiceModel.FaultException<>))
        {
            var property = exceptionType.GetProperty("Detail");
            return property.GetValue(ex, null) as System.ServiceModel.ExceptionDetail;
        }

        exceptionType = exceptionType.BaseType;
    }
    return null;
}

O co zde šlo?

Máme hodnotu, která je přímo nebo je odvozená z typu FaultException<TDetail> pro nějaké libovolné TDetail. Typ TDetail tedy není předem známý. Úkolem je získat hodnotu vlastnosti Detail (která je typu TDetail) definované na FaultException<TDetail>. (V našem případě nás hodnota vlastnosti Detail zajímala pouze pokud je nebo je odvozená z typu ExceptionDetail, ale to už je ta méně podstatná a jednoduchá část.)

Toto je docela hezký příklad na použití reflection pro manipulaci s generickými typy. V uvedeném řešení bych hlavně vypíchnul následující:

  • Na začátku provádíme test zda je hodnota ex typu FaultException. Tento test je zde z důvodu optimalizace. Protože typ FaultException<TDetail> dědí z typu FaultException, platí, že pokud nebude ex typu FaultException nemůže být ani typu FaultException<TDetail> pro libovolné TDetail. V takovém případě se do žádné reflexe nemusíme vůbec pouštět (reflexe je obecně pomalá).
  • Celé řešení je v cyklu while, kdy se začíná zkoumáním typu ex.GetType() a pak se v případných dalších iteracích zkoumají postupně typy exceptionType.BaseType. Toto je nutné pokud bude ex typu odvozeného z FaultException<TDetail> a ne FaultException<TDetail> přímo.
  • V každé iteraci se pak zkoumá zda je exceptionType generický typ a jeho tzv. generic type definice je typu FaultException<>.
  • Pokud je toto splněno provede se již pouze vlastní vytažení hodnoty vlastnosti Detail (díky předchozímu testu je zajištěno, že toto neselže).

 

hodnocení článku

0       Hodnotit mohou jen registrované uživatelé.

 

Nový příspěvek

 

                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback