594 Stimmen

Programmatische Entsprechung von default(Typ)

Ich verwende Reflexion, um eine Schleife durch eine Type Eigenschaften und setzen bestimmte Typen auf ihre Standardwerte. Jetzt könnte ich den Typ umschalten und die default(Type) explizit, aber ich würde es lieber in einer Zeile machen. Gibt es ein programmatisches Äquivalent zu default?

800voto

Dror Helper Punkte 29647
  • Im Falle eines Werttyps verwenden Sie Aktivator.CreateInstance und es sollte gut funktionieren.
  • Bei Verwendung eines Referenztyps einfach null zurückgeben

    public static object GetDefault(Type type) { if(type.IsValueType) { return Activator.CreateInstance(type); } return null; }

In den neueren Versionen von .net wie .net standard, type.IsValueType muss geschrieben werden als type.GetTypeInfo().IsValueType

117voto

Drakarah Punkte 2194

Warum nicht die Methode, die default(T) zurückgibt, mit reflection aufrufen? Sie können GetDefault von jedem Typ mit verwenden:

    public object GetDefault(Type t)
    {
        return this.GetType().GetMethod("GetDefaultGeneric").MakeGenericMethod(t).Invoke(this, null);
    }

    public T GetDefaultGeneric<T>()
    {
        return default(T);
    }

97voto

JoelFan Punkte 35927

Sie können verwenden PropertyInfo.SetValue(obj, null) . Bei einem Aufruf für einen Werttyp wird der Standardwert angezeigt. Dieses Verhalten ist dokumentiert in .NET 4.0 y in .NET 4.5 .

58voto

casperOne Punkte 72238

Wenn Sie .NET 4.0 oder höher verwenden und eine programmatische Version wünschen, die keine Kodifizierung von definierten Regeln ist außerhalb des Codes können Sie eine Expression kompilieren und sofort ausführen.

Die folgende Erweiterungsmethode nimmt eine Type und erhalten den Wert, der von default(T) durch die Default Methode について Expression Klasse:

public static T GetDefaultValue<T>()
{
    // We want an Func<T> which returns the default.
    // Create that expression here.
    Expression<Func<T>> e = Expression.Lambda<Func<T>>(
        // The default value, always get what the *code* tells us.
        Expression.Default(typeof(T))
    );

    // Compile and return the value.
    return e.Compile()();
}

public static object GetDefaultValue(this Type type)
{
    // Validate parameters.
    if (type == null) throw new ArgumentNullException("type");

    // We want an Func<object> which returns the default.
    // Create that expression here.
    Expression<Func<object>> e = Expression.Lambda<Func<object>>(
        // Have to convert to object.
        Expression.Convert(
            // The default value, always get what the *code* tells us.
            Expression.Default(type), typeof(object)
        )
    );

    // Compile and return the value.
    return e.Compile()();
}

Sie sollten den obigen Wert auch auf der Grundlage des Cache Type aber seien Sie sich darüber im Klaren, wenn Sie dies für eine große Anzahl von Type Instanzen, und verwenden Sie ihn nicht ständig, könnte der vom Cache verbrauchte Speicher die Vorteile überwiegen.

41voto

Rob Fonseca-Ensor Punkte 15345

Warum sagen Sie, dass Generika nicht mehr in Frage kommen?

    public static object GetDefault(Type t)
    {
        Func<object> f = GetDefault<object>;
        return f.Method.GetGenericMethodDefinition().MakeGenericMethod(t).Invoke(null, null);
    }

    private static T GetDefault<T>()
    {
        return default(T);
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X