1

I'm learning about generics in C#, and I'm trying to make a generic array and add some strings to it. I can easily add int values to it, but I can't figure out how to make it work with strings. When I'm trying to use strings I get NullReferenceException.

I have a class called myArray, and it looks like this:

class MyArray<T> : IComparable<T>, IEnumerable<T>, IEnumerator<T>
{
    T[] data = new T[10];
    int current = -1;

    public T[] Data
    {
        get { return data; }
    }

    public void Add(T value)
    {
        for (int i = 0; i < data.Length; i++)
        {
            if (data[i].Equals(default(T)))
            {
                data[i] = value;
                return;
            }
        }
        T[] tmp = new T[data.Length + 10];
        data.CopyTo(tmp, 0);
        Add(value);
    }

In my mainform I add the data like this:

class Program
{
    static void Main(string[] args)
    {
        MyArray<string> StringArray = new MyArray<string>();

        StringArray.Add("ONE");
        StringArray.Add("TWO");
    }
}
2
  • 3
    why compare to default(T)? why not just track how many you have? Or... just use List<T>... Commented Mar 4, 2011 at 20:25
  • damn everyone is so fast:) i debugged code and its about your for loop as everyone suggested. with new T[10] you have an array of T but array[0] is null cause you havent added anything there yet. Commented Mar 4, 2011 at 20:30

3 Answers 3

3

The default of string is null as it is a reference type, not a value type. You are constructing a new array of type T[], which results in an array filled with the default value of T, which in this case is null.

Following that, data[i].Equals(default(T)) throws NRE as you are trying to call null.Equals(...).

Sign up to request clarification or add additional context in comments.

Comments

1

Your array is being initialized with null values, so you're getting a NRE at this line:

if (data[i].Equals(default(T)))

Comments

0

if (data[i].Equals(default(T))) is where the issue lies. In a new string (or any other reference type) array,

var array = new String[10];

each element in the array is null by default. So when you say

data[i].Equals(default(T)

and data[i] is null, you're calling a method on a null reference, thus causing the exception to be thrown.

This doesn't happen for value types, as the array is initialized to the default value of whatever the value type is.

This is part of the problem with generics--you can't always treat reference types and value types the same.

Try this instead, to avoid default:

private int _currentIndex = 0;
public void Add(T value)
{
    data[_currentIndex] = value;
    _currentIndex++;
    if(_currentIndex == data.Length)
    {
       T[] tmp = new T[data.Length + 10];
        data.CopyTo(tmp, 0);
        data = tmp;
        _currentIndex = 0;
    }          
}

3 Comments

Equals isn't the problem here - according to msdn, Equals shouldn't throw at all (by convention).
wasn't meant as an attack towards you, I fell for it as well at first, my text was just too ambigious for it to stick out. Using an index counter is better anyway.
@Fem lol no attack, I re-read my answer after your comment and realized it sounded exactly like you took it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.