检查generic是否为0

时间:2016-04-01 17:06:59

标签: c# generics

我正在尝试编写自己的收藏。当然,它包含通用值。当我试图检查数组 _content 的值是否为空时 - 它运行良好,但前提是用户不使用整数。

 if (_content[_size - 1] != null)

关键是用户可以创建整数集合,而数组会将所有值初始化为0。因此,当我尝试检查值是否为0时 - 它不会编译。

if (_content[_size - 1] != 0)

特别是没有使用此方法(如果集合由整数组成):

public void Add(T item)
{
        if (_content[_size - 1] != null)
            throw new ArgumentOutOfRangeException("The Array is full");
        if (_size > 0)
        {
            for (int i = 0; i <= _size; i++)
            {
                if (_content[i] == null)
                {
                    _content[i] = item;
                    break;
                }
            }
        }

}

4 个答案:

答案 0 :(得分:7)

你要做的是一种不好的做法,所以不要这样做。

您的方法保留一个值,即零,以表示&#34;没有&#34;。但是,零和零之间存在差异,因此当零是合法值时,您的方法会导致错误。

考虑当您的收藏集的用户为最后一个数字添加零时会发生什么。你的代码会认为单元格是空的,而不是应该抛出异常。

更好的方法是在_size字段中存储已在集合中设置的实际元素数。 _content的最后一个元素位于_content.Length-1,因此您可以按以下方式进行检查:

if (_content.Length == _size) {
    // InvalidOperationException is more appropriate here,
    // because the error is caused by the state of your collection,
    // rather than any particular argument passed to the method.
    throw new InvalidOperationException("The Array is full");
}

答案 1 :(得分:1)

您可以在泛型类型上使用print ''.join(c for c in sha2 if c.isalnum()) 关键字,它返回该类型的默认值(即引用类型为null,值类型为0或false等)。

编辑:上一个示例会崩溃: - )

所以试试:

default

另见其他解决方案的评论。

答案 2 :(得分:1)

您可以使用default关键字检查某个值是否等于其类型的默认值,即类null,数字0等。

您还需要使用Object.Equals(a,b)EqualityComparer<T>.Default.Equals(),因为==运算符不能保证在类T上可用,因此无法编译。

所以你的方法看起来像:

public void Add(T item)
{
    if (!EqualityComparer<T>.Default.Equals(_content[_size - 1], default (T)))
        throw new ArgumentOutOfRangeException("The Array is full");
    if (_size > 0)
    {
        for (int i = 0; i <= _size; i++)
        {
            if (EqualityComparer<T>.Default.Equals(_content[i], default (T)))
            {
                _content[i] = item;
                break;
            }
        }
    }
}

答案 3 :(得分:0)

您检查null的问题是无法将值类型(结构,整数等)与null进行比较。

您可以在这里采取一些不同的方法。一种是约束可以与泛型集合类一起使用的类型。这样,您可以确保仅将可空类型(即引用类型)用作集合的类型定义。

public class MyCollection<T> where T : class

或者,您可以使用反射:

检查类型是否为引用类型,然后再将其与null进行比较

typeof(T).IsValueType

请勿检查特定类型 - 这里的问题是您将非可空类型与null进行比较。