Tech Xie
Tech Xie

Reputation: 927

Generic return type in C#

Was practicing Generics. Consider a stack method below. What is the best way of doing error checking other than throwing exceptions in a generic method. What if I want to return some result in this method.

public T pop()
{
    if (top >= 0)
        return arr[top--];
    return -1 or null;
}

Upvotes: 13

Views: 17689

Answers (7)

David Gray
David Gray

Reputation: 11

I came here in search of a solution to a slightly different issue, involving a static method that takes two generic arrays and returns a new generic array. Since my method was static, I couldn't use the example, except as inspiration. Instead, I developed the following solution.

T [ ] raMerged = ( T [ ] ) alMerged.ToArray ( typeof ( T ) );
return raMerged;

In the above snippet, alMerged is an ArrayList of generic objects T.

This satisfies the conditions of the contract specified by the method signature, which is as follows.

public static T [ ] MergeNewItemsIntoArray<T> (
T [ ] paMasterList ,
T [ ] paNewItems )
where T : IComparable , new ( )

In the signature, the where clause illustrates my resolution of another issue that I found in several threads, none of which directly addressed this question. Nevertheless, hopefully, this will help at least one other soul.

Upvotes: 1

Andrey
Andrey

Reputation: 777

Direct approach (use generics and return value or null)

class DemoClass<T> where T : struct
{
   public T? PopValueOrNull() 
   { 
     if ( this._top >= 0 ) { 
        return this._arr[this._top--];
      } 

      return null; 
    }
}

Upvotes: 0

If you want to be able to return null when the stack is empty you can try something like this:

class GenericStack<T>
{
    T[] arr;
    int top;

    public T pop()
    {
        if (top >= 0)
            return arr[top--];
        return default(T);
    }
}

And then you can use use like this:

        var stack = new GenericStack<int?>();

        var res = stack.pop(); // res will be null

Notice the stack object is of type int? so we can return nulls.

Upvotes: 0

Trillian
Trillian

Reputation: 6447

The only thing you could do is return default(T), which is the default value for the type T (null for reference types, zero for integral types and zeroed-fields object for other value types). However, this is generally a bad idea as you'll have no way to distinguish between a 0 that was popped or a 0 that indicates an error. Exceptions are generally the best way to go in such cases, but you could also change your method as follows:

public bool TryPop(out T value)
{
    if (top >= 0)
    {
        value = arr[top--];
        return true;
    }
    value = default(T);
    return false;
}

Upvotes: 15

&#181;Bio
&#181;Bio

Reputation: 10758

You could do return default(T), which will return 0 initialized value types (ex. all numeric types will be initialized to 0), and null for reference types.

Upvotes: 6

JaredPar
JaredPar

Reputation: 755457

It seems like your question really has two parts

The first part being how to provide a default value if one is not available. As other people have pointed out the C# expression default(T) will work for this scenario. It returns null for reference types and 0 initialized values for structs.

The second part being what is the best way to handle the error case other than to throw an exception. Collection APIs tend to use the TryXXX pattern for this type of scenario

bool TryPop(out T value) { 
  if ( top >= 0 ) {
    value = arr[top--];
    return true;
  }
  value = default(T);
  return false;
}

Upvotes: 1

EMP
EMP

Reputation: 62031

Your question is unclear. Error checking can be done the same ways as always - catching exceptions. Raising errors should generally be done by throwing exceptions. That is what they're for, after all.

If you want to return null you can do that, but then you have to make sure that type T is a class, not a struct, like so:

public T pop()
    where T: class
{
     ...
}

Upvotes: 0

Related Questions