Darkreaper
Darkreaper

Reputation: 21

Nullable generic object collection

public class CubicMatrix<Object?>
    {
        private int width;
        private int height;
        private int depth;
        private Object[, ,] matrix;

        public CubicMatrix(int inWidth, int inHeight, int inDepth)
        {
            width = inWidth;
            height = inHeight;
            depth = inDepth;
            matrix = new Object[inWidth, inHeight, inDepth];
        }

        public void Add(Object toAdd, int x, int y, int z)
        {
            matrix[x, y, z] = toAdd;
        }

        public void Remove(int x, int y, int z)
        {
            matrix[x, y, z] = null;
        }

        public void Remove(Object toRemove)
        {
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int z = 0; z < depth; z++)
                    {
                        Object value = matrix[x, y, z];
                        bool match = value.Equals(toRemove);
                        if (match == false)
                        {
                            continue;
                        }

                        matrix[x, y, z] = null;
                    }
                }
            }
        }

        public IEnumerable<Object> Values
        {
            get
            {
                LinkedList<Object> allValues = new LinkedList<Object>();
                foreach (Object entry in matrix)
                {
                    allValues.AddLast(entry);
                }
                return allValues.AsEnumerable<Object>();
            }
        }

        public Object this[int x, int y, int z]
        {
            get
            {
                return matrix[x, y, z];
            }
        }

        public IEnumerable<Object> RangeInclusive(int x1, int x2, int y1, int y2, int z1, int z2)
        {
            LinkedList<Object> list = new LinkedList<object>();
            for (int a = x1; a <= x2; a++)
            {
                for (int b = y1; b <= y2; b++)
                {
                    for (int c = z1; c <= z2; c++)
                    {
                        Object toAdd = matrix[a, b, c];
                        list.AddLast(toAdd);
                    }
                }
            }

            return list.AsEnumerable<Object>();
        }

        public bool Available(int x, int y, int z)
        {
            Object toCheck = matrix[x, y, z];
            if (toCheck != null)
            {
                return false;
            }

            return true;
        }
    }

I've created a Cubic Matrix class in C# to store items in 3 dimensions. I need to be able to add and remove items which is why I'm using Object? (I've been led to understand that you can't use nullable generics ie. T?). However this approach gnerates an error

Type parameter declaration must be an identifier not a type

If i don't use Object? though and just use Object or T i get this error instead

Cannot convert null to type parameter 'T' because it could be a non-nullable value type. Consider using 'default(T)' instead.

What's the correct syntax and approach to use in this case?

Upvotes: 1

Views: 485

Answers (3)

Kirk Broadhurst
Kirk Broadhurst

Reputation: 28728

If you want to restrict your generic type to objects only - i.e. no structs or simple types - you can add the where clause

public class CubicMatrix<T> where T : class

These means that T can only be a class.

Upvotes: 3

31eee384
31eee384

Reputation: 2803

I think you want to use the generic parameter T. You're making a simple container class, so allowing any generic parameter makes sense, whether it's nullable or not. To fix the error, just do what it says and use default(T) instead of null.

The error is because T could be a class or a struct, and structs can't be null. Therefore assigning a variable with type T to null is invalid. default(T) is null when T is a class and default values when T is a struct.

Upvotes: 1

trashr0x
trashr0x

Reputation: 6575

When returning default(T) instead (as the error you are getting suggests), reference types will return null, numeric types will return 0, your custom classes will return null and nullables will return System.Nullable<T>. More about this in default Keyword in Generic Code (C# Programming Guide) on MSDN.

Upvotes: 1

Related Questions