2009-08-15 20 views

risposta

62

Dato che devi solo preoccuparti dei tipi di valore (i tipi di riferimento saranno null), puoi utilizzare Activator.CreateInstance per richiamare su di essi il costruttore predefinito.

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

Modifica: Jon è (ovviamente) corretto. IsClass non è abbastanza esaustivo - restituisce False se type è un'interfaccia.

+18

Meglio usare! Type.IsValueType, per far fronte alle interfacce. –

+0

grazie ragazzi! questo è quello che stavo cercando! –

1

Senza un generico, non si può garantire che il tipo ha un costruttore senza parametri, ma è possibile cercare un utilizzando la riflessione:

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

ho provato questo in una console app, ed è restituisce un'istanza "predefinita" della classe — assumendo che si tratti di una classe. Se hai bisogno che funzioni anche per i tipi di riferimento, avrai bisogno di una tecnica aggiuntiva.

+3

Il valore predefinito per il tipo di riferimento è null e non un'istanza della classe. Quindi, se fa ciò che tu suggerisci, GetDefault (T) restituirà null mentre GetDefault (Type) proverà a creare un'istanza, se possibile, che è sbagliata. La tua tecnica non è inutile, ma immagino che sia più simile a "T GetInstance (T) dove T: new() {return new T();}" tipo di metodo. – JohannesH

+0

Capisco cosa intendi. Grazie per la correzione! – harpo

+0

La tua risposta è molto utile. – rolls

7

Ecco come faccio normalmente. Ciò evita l'intero 'IsValueType' o la ricerca di problemi con i costruttori.

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

Puoi spiegare come è diverso/migliore/peggiore di quello di Mark Brackett? – rolls

+0

Non posso dire che sia meglio o peggio; dipende dai tuoi bisogni, suppongo. La mia risposta è quasi certamente più lenta senza alcun caching. L'unica cosa che mi piace particolarmente di questa soluzione è che utilizza la funzione di linguaggio incorporato che stiamo cercando di emulare; piuttosto che simularlo. – jonfuller

Problemi correlati