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?

28voto

cuft Punkte 261

Dies ist die optimierte Lösung von Flem:

using System.Collections.Concurrent;

namespace System
{
    public static class TypeExtension
    {
        //a thread-safe way to hold default instances created at run-time
        private static ConcurrentDictionary<Type, object> typeDefaults =
           new ConcurrentDictionary<Type, object>();

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

7voto

BSick7 Punkte 575

Die gewählte Antwort ist eine gute Antwort, aber seien Sie vorsichtig mit dem zurückgegebenen Objekt.

string test = null;
string test2 = "";
if (test is string)
     Console.WriteLine("This will never be hit.");
if (test2 is string)
     Console.WriteLine("Always hit.");

Extrapolieren...

string test = GetDefault(typeof(string));
if (test is string)
     Console.WriteLine("This will never be hit.");

5voto

kpollock Punkte 3759

Ich erledige die gleiche Aufgabe auf diese Weise.

//in MessageHeader 
   private void SetValuesDefault()
   {
        MessageHeader header = this;             
        Framework.ObjectPropertyHelper.SetPropertiesToDefault<MessageHeader>(this);
   }

//in ObjectPropertyHelper
   public static void SetPropertiesToDefault<T>(T obj) 
   {
            Type objectType = typeof(T);

            System.Reflection.PropertyInfo [] props = objectType.GetProperties();

            foreach (System.Reflection.PropertyInfo property in props)
            {
                if (property.CanWrite)
                {
                    string propertyName = property.Name;
                    Type propertyType = property.PropertyType;

                    object value = TypeHelper.DefaultForType(propertyType);
                    property.SetValue(obj, value, null);
                }
            }
    }

//in TypeHelper
    public static object DefaultForType(Type targetType)
    {
        return targetType.IsValueType ? Activator.CreateInstance(targetType) : null;
    }

3voto

Konstantin Isaev Punkte 602

Die Expressions können hier helfen:

    private static Dictionary<Type, Delegate> lambdasMap = new Dictionary<Type, Delegate>();

    private object GetTypedNull(Type type)
    {
        Delegate func;
        if (!lambdasMap.TryGetValue(type, out func))
        {
            var body = Expression.Default(type);
            var lambda = Expression.Lambda(body);
            func = lambda.Compile();
            lambdasMap[type] = func;
        }
        return func.DynamicInvoke();
    }

Ich habe dieses Snippet nicht getestet, aber ich denke, es sollte "typisierte" Nullen für Referenztypen produzieren

3voto

Paul Fleming Punkte 23538

Entspricht der Antwort von Dror, aber als Erweiterungsmethode:

namespace System
{
    public static class TypeExtensions
    {
        public static object Default(this Type type)
        {
            object output = null;

            if (type.IsValueType)
            {
                output = Activator.CreateInstance(type);
            }

            return output;
        }
    }
}

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