2010-04-26 12 views
6

Jak napisać prostą metodę, która sprawdza, czy konkretny typ jest niestandardową strukturą (utworzoną przy użyciu public struct { };), czy nie.Jak ustalić, czy typ .NET jest niestandardową strukturą?

Sprawdzanie Type.IsValueType nie wystarczy, ponieważ prawdą jest również, aby int, long, itp, i dodanie czek !IsPrimitiveType nie wyklucza decimal, DateTime a może jakieś inne typy wartości. Wiem, że większość z wbudowanych typów wartości są rzeczywiście „elemencie”, ale chcę tylko, aby sprawdzić „niestandardowych elemencie”

Te pytania są w większości takie same, ale bez odpowiedzi muszę:

EDIT: z odpowiedzi wspomniał "sprawdzić przedrostka 'system'" był najbardziej stabilny (choć wciąż jest hackerem). W końcu zdecydowałem się na stworzenie Atrybutu, który musisz udekorować strukturą, aby struktura podniosła go jako niestandardową strukturę. (Drugi wybór myślałem było utworzyć pusty interfejs i niech struct realizacji tego pustego interfejsu, ale sposób atrybut wydawał się bardziej elegancki)

Oto mój oryginalny kontroler niestandardowego struct jeśli ktoś jeżeli zainteresowany:

type.IsValueType && !type.IsPrimitive && !type.Namespace.StartsWith("System") && !type.IsEnum 
+1

Po prostu z ciekawości, dlaczego chcesz to wykryć? – Joren

+0

Fluent NHibernate + Auto Mapping: ustaw wszystkie niestandardowe konstrukcje, które będą traktowane jako komponenty (obiekty wartości); ustawienie dowolnego innego typu elementu na komponent (np. DateTime lub dziesiętny) spowoduje awarię całego frameworka (przynajmniej w mono) – SztupY

+0

Add on! type.IsEnum –

Odpowiedz

5

Cóż, DateTime, dziesiętne itp. Spełniają Twoje wymagania. Jeśli chodzi o CLR, są one niestandardowymi strukturami. Hack, ale możesz po prostu sprawdzić, czy obszar nazw zaczyna się od "System".

+0

Oczywiście Twoja własna przestrzeń nazw może zaczynać się od System ...:) Nikt by tego nie zrobił, prawda? –

+2

Tak, dlatego nazwałem to hackem. –

+0

@MattGreer: świetny hack przy okazji, nie mogłem o tym myśleć :) dzięki –

8

Nie ma różnicy między strukturą zdefiniowaną w ramach a strukturą zdefiniowaną przez użytkownika.

Kilka pomysłów mogłoby być:

  • Zachowaj białej listy strukturach ramowych i wykluczyć te;
  • Zidentyfikuj zespół (DLL), w którym zdefiniowano typ, i zachowaj białą listę zespołów szkieletów.
  • Identyfikuje przestrzeń nazw, w której znajduje się typ, i wyklucza ramki strukturalne.
+0

W kontekście komentarza na temat Fluent NHibernate, najlepszym podejściem byłaby biała lista "dobrze znanych" struktur. Lista jest na tyle krótka, że ​​można ją łatwo zrozumieć i prawdopodobnie nigdy się nie zmieni. –

+0

Uzgodniono, że każdy, który powoduje awarię, dodaj go do białej listy (lub czarnej listy lub jakkolwiek to nazwiesz) i kontynuuj. Struktura nie ma zbyt wielu struktur. – stusmith

+0

Tak, ale niestety nie ma tam żadnych list. A jeśli czegoś nie zauważysz i użyjesz tej struktury później, nie będziesz wiedział, dlaczego frameworki zaczynają się zawieszać – SztupY

2

Można sprawdzić, czy typ struktury mieści się w dowolnym miejscu w obrębie System nazw systemowych. Ale znowu to nie jest niezawodne rozwiązanie.

3

wprowadzenie powyższych uwag do metody przedłużeniu:

public static class ReflectionExtensions { 
     public static bool IsCustomValueType(this Type type) {    
       return type.IsValueType && !type.IsPrimitive && type.Namespace != null && !type.Namespace.StartsWith("System."); 
     } 
    } 

powinien działać

-1

Czy masz wartość, która wychodzi z tego typu? Wywołaj metodę ToString i sprawdź, czy zwracany ciąg zaczyna się od "{".

Jeśli nie masz wartości, sprawdź, czy ma konstruktor bez parametrów. Jeśli nie, jest to konstruktor. Jeśli tak, użyj Activator, aby utworzyć instancję i ponownie wywołać metodę ToString.

Powiązane problemy