c# – default(T)与空集合而不是null

前端之家收集整理的这篇文章主要介绍了c# – default(T)与空集合而不是null前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想要通用的方法返回传递类型的默认值,但是对于集合类型,我想获取空集合而不是null,例如:
GetDefault<int[]>(); // returns empty array of int's
GetDefault<int>(); // returns 0
GetDefault<object>(); // returns null
GetDefault<IList<object>>(); // returns empty list of objects

我开始写的方法如下:

public static T GetDefault<T>()
{
   var type = typeof(T);
   if(type.GetInterface("IEnumerable") != null))
   {
      //return empty collection
   }
   return default(T);   
}

如何完成?

编辑:
如果任何人想要获取某些类型的默认值,则基于类型实例而不是类型标识符,可以使用以下结构,即:

typeof(int[]).GetDefault();

内部实现是基于@ 280Z28的答案:

public static class TypeExtensions
{
    public static object GetDefault(this Type t)
    {
        var type = typeof(Default<>).MakeGenericType(t);
        var property = type.GetProperty("Value",BindingFlags.Static | BindingFlags.Public);
        var getaccessor = property.GetGetMethod();
        return getaccessor.Invoke(null,null);
    }
}

解决方法

您可以使用静态构造函数的魔术来高效地执行此操作.要使用代码中的默认值,只需使用Default< T> .Value.在应用期间,该值仅对任何给定类型T一次进行评估.
public static class Default<T>
{
    private static readonly T _value;

    static Default()
    {
        if (typeof(T).IsArray)
        {
            if (typeof(T).GetArrayRank() > 1)
                _value = (T)(object)Array.CreateInstance(typeof(T).GetElementType(),new int[typeof(T).GetArrayRank()]);
            else
                _value = (T)(object)Array.CreateInstance(typeof(T).GetElementType(),0);
            return;
        }

        if (typeof(T) == typeof(string))
        {
            // string is IEnumerable<char>,but don't want to treat it like a collection
            _value = default(T);
            return;
        }

        if (typeof(IEnumerable).IsAssignableFrom(typeof(T)))
        {
            // check if an empty array is an instance of T
            if (typeof(T).IsAssignableFrom(typeof(object[])))
            {
                _value = (T)(object)new object[0];
                return;
            }

            if (typeof(T).IsGenericType && typeof(T).GetGenericArguments().Length == 1)
            {
                Type elementType = typeof(T).GetGenericArguments()[0];
                if (typeof(T).IsAssignableFrom(elementType.MakeArrayType()))
                {
                    _value = (T)(object)Array.CreateInstance(elementType,0);
                    return;
                }
            }

            throw new NotImplementedException("No default value is implemented for type " + typeof(T).FullName);
        }

        _value = default(T);
    }

    public static T Value
    {
        get
        {
            return _value;
        }
    }
}

猜你在找的C#相关文章