2016-01-02 61 views
1

我有一个通用的Array2D类,并且想要添加一个isEmpty获取器。但在这种情况下,T无法与default(T)通过!=进行比较。并且Equals()不能使用,因为该字段可能是null(但请参阅下面的代码)。我如何能够检查所有字段是否为空(即引用类型或结构体等的缺省值)?检查通用数组的空(默认)字段

到目前为止,我提出了以下解决方案,但对于简单的isEmpty检查,它似乎已经相当冗长,并且它可能不是解决此问题的最佳方法。任何人都知道更好的解决方案?

public sealed class Array2D<T> 
{ 
    private T[,] _fields; 
    private int _width; 
    private int _height; 

    public bool isEmpty 
    { 
     get 
     { 
      for (int x = 0; x < _width; x++) 
      { 
       for (int y = 0; y < _height; y++) 
       { 
        if (_fields[x, y] != null && !_fields[x, y].Equals(default(T))) return false; 
       } 
      } 
      return true; 
     } 
    } 

    public Array2D(int width, int height) 
    { 
     _width = width < 0 ? 0 : width; 
     _height = height < 0 ? 0 : height; 
     _fields = new T[width, height]; 
    } 
} 
+0

我不认为有另一种方式(在性能方面):你仍然需要通过每个元素。也许你可以做一个“foreach”来替换这两个“for”,并用另一种方法进行迭代。 –

+2

如果此特定检查的性能很重要,只需检查“索引器”中的非默认值的分配(但是您已在[i,j]中实现了“set element”) –

回答

2

而不是通过所有IsEmpty元素的循环,只需更新IsEmpty值时设置的值(需要一个索引,但是你可能需要一个反正):

public class Array2<T> 
{ 
    private readonly T[,] _array; 
    private bool _isEmpty; 

    public Array2(int width, int height) 
    { 
     _array = new T[width, height]; 
     _isEmpty = true; 
    } 

    public T this[int x, int y] 
    { 
     get { return _array[x, y]; } 
     set 
     { 
      _array[x, y] = value; 
      _isEmpty = _isEmpty && value.Equals(default(T)); 
     } 
    } 

    public bool IsEmpty 
    { 
     get { return _isEmpty; } 
    } 
} 

例:

Array2<int> array2 = new Array2<int>(10, 10); 
array2[0, 0] = 0; 
Console.WriteLine(array2.IsEmpty); 
array2[0, 0] = 1; 
Console.WriteLine(array2.IsEmpty); 
array2[0, 0] = 0; 
Console.WriteLine(array2.IsEmpty); 

输出:

True 
False 
False 

显然这是一个折衷,但想象一下,你有100万个元素的数组,你的循环运行100万次。采用这种方法不会出现循环,只能在任何时候检查2个条件。

+0

谢谢!这在大多数情况下都适用。现在同时我必须让IEnmmerable这个类,所以我实现了枚举代码根据https://msdn.microsoft.com/en-us/library/ee5kxzk0(v=vs.90).aspx ...所以我用foreach循环取代了依赖于枚举器的循环,但仍然是一个循环,但是在我的代码中,数组永远不会真的那么大。 – BadmintonCat

+0

乐意提供帮助! – Aybe