Programmatic equivalent of default(Type)

前端 未结 14 1493
时光取名叫无心
时光取名叫无心 2020-11-22 05:28

I\'m using reflection to loop through a Type\'s properties and set certain types to their default. Now, I could do a switch on the type and set the defau

相关标签:
14条回答
  • 2020-11-22 06:10

    Why do you say generics are out of the picture?

        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);
        }
    
    0 讨论(0)
  • 2020-11-22 06:10

    This is optimized Flem's solution:

    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;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 06:16

    Equivalent to Dror's answer but as an extension method:

    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;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 06:19

    I do the same task like this.

    //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;
        }
    
    0 讨论(0)
  • 2020-11-22 06:20

    You can use PropertyInfo.SetValue(obj, null). If called on a value type it will give you the default. This behavior is documented in .NET 4.0 and in .NET 4.5.

    0 讨论(0)
  • 2020-11-22 06:22

    The chosen answer is a good answer, but be careful with the object returned.

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

    Extrapolating...

    string test = GetDefault(typeof(string));
    if (test is string)
         Console.WriteLine("This will never be hit.");
    
    0 讨论(0)
提交回复
热议问题