2009-08-15 11 views

Odpowiedz

62

Ponieważ naprawdę musisz martwić się tylko o typy wartości (typy referencji będą miały wartość zerową), możesz użyć Activator.CreateInstance, aby wywołać na nich domyślny konstruktor.

public static object GetDefaultValue(Type type) { 
    return type.IsValueType ? Activator.CreateInstance(type) : null; 
} 

Edytuj: Jon jest (oczywiście) poprawny. IsClass nie jest wystarczająco wyczerpujący - zwraca False, jeśli interfejs to type.

+18

Lepsze w użyciu! Type.IsValueType, aby poradzić sobie z interfejsami. –

+0

dzięki chłopaki! właśnie tego szukałem! –

1

Bez generycznym, nie można zagwarantować, że typ ma konstruktora bez parametrów, ale można wyszukać za pomocą jednej refleksji:

public static object GetDefaultValue(Type type) 
{ 
    ConstructorInfo ci = type.GetConstructor(new Type[] {}); 
    return ci.Invoke(new object[] {}); 
} 

Próbowałem to w aplikacji konsoli, a to zwraca "domyślną" instancję klasy — zakładając, że jest klasą. Jeśli potrzebujesz go również do pracy z typami referencyjnymi, potrzebujesz dodatkowej techniki.

+3

Domyślną wartością dla typu odniesienia jest null, a nie instancja klasy. Więc jeśli robi to, co sugerujesz, GetDefault (T) zwróci wartość null, podczas gdy GetDefault (Type) spróbuje wykonać instancję, jeśli to możliwe, co jest błędne. Technika nie jest bezużyteczna, ale przypuszczam, że jest bardziej jak "T GetInstance (T), gdzie metoda T: new() {return new T();}". – JohannesH

+0

Widzę, co masz na myśli. Dziękuję za poprawienie mnie! – harpo

+0

Twoja odpowiedź jest bardzo przydatna. – rolls

7

Oto, jak zwykle to robię. Dzięki temu unika się całego "IsValueType" lub w ogóle wyszukiwania problemów konstruktorów.

public static object MakeDefault(this Type type) 
{ 
    var makeDefault = typeof(ExtReflection).GetMethod("MakeDefaultGeneric"); 
    var typed = makeDefault.MakeGenericMethod(type); 
    return typed.Invoke(null, new object[] { }); 
} 

public static T MakeDefaultGeneric<T>() 
{ 
    return default(T); 
} 
+0

Czy możesz wyjaśnić, jak to jest inne/lepsze/gorsze niż odpowiedź Marka Bracketta? – rolls

+0

Nie mogę powiedzieć, że jest lepiej lub gorzej; zależy od twoich potrzeb, jak przypuszczam. Moja odpowiedź jest prawie na pewno wolniejsza bez buforowania. Jedno, co szczególnie podoba mi się w tym rozwiązaniu, to to, że korzysta z wbudowanej funkcji językowej, którą próbujemy naśladować; zamiast symulować to. – jonfuller