我使用反射来循环一个类型的属性,并将某些类型设置为默认值。现在,我可以在类型上进行切换,并显式地设置默认(type),但我宁愿在一行中完成。在编程中是否存在与默认设置相同的功能?


当前回答

下面的表达可以帮助你:

    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();
    }

我没有测试这个片段,但我认为它应该为引用类型产生“类型化”空值。

其他回答

相当于Dror的答案,但作为一种扩展方法:

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;
        }
    }
}

下面的表达可以帮助你:

    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();
    }

我没有测试这个片段,但我认为它应该为引用类型产生“类型化”空值。

这应该可以工作: null <T> a = new Nullable<T>().GetValueOrDefault();

所选的答案是一个很好的答案,但要注意返回的对象。

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

推断……

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

如果你已经创建了一个对象,你可以尝试…

var yourObj = new yourObj();
var properties = yourObj.GetType().GetProperties();

foreach (var p in properties)
{
    // you can get default value for each property
    var defaultValue = p.GetValue(yourObj, null);
}