Array.Find Generic Method (System) [newbie]

  • Thread starter Thread starter Erica
  • Start date Start date
E

Erica

Hi, is there a standard way of handling null with System.Array.Find methods?
For instance, currently I must do the following;

Fruit[] filterFruits = null;
if (arrayOfFruits != null)
{
filterFruits =
Array.FindAll(arrayOfFruits,
delegate(Fruit fruit)
{
// skip over apples
return (fruit.kind != Fruit.TypeOfFruit.Apple);
});
}

Is there a best practice for handling null or is the way that I am doing it
the best way; Array.FindAll throws ArgumentNullException if array is a null
reference. I looked at msdn2 site and they don't suggest any best practices
for this.

Thanks,
 
I ask because I find myself testing for null in a lot of places; I was
thinking about creating a static method as follows;

public static TOutput[] ConvertArray<TInput, TOutput>(
TInput[] array,
Converter<TInput, TOutput> converter)
{
if (array == null)
{
return (TOutput[])null;
}
else
{
return Array.ConvertAll(array, converter);
}
}

Then I would simply call this method to do conversion like this;
Converter<int, string> converter = new Converter<int,
string>(IntToString);
string[] sarr = ConvertArray<int, string>(arr, converter);
Is this a good practice or is there a better way of this that a newbie such
as myself is oblivious too?

PS: disassembly of ConvertAll:

public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] array,
Converter<TInput, TOutput> converter)
{
if (array == null)
{
throw new ArgumentNullExcepti­on("array");
}
if (converter == null)
{
throw new ArgumentNullExcepti­on("converter");
}
TOutput[] localArray1 = new TOutput[array.Length];
for (int num1 = 0; num1 < array.Length; num1++)
{
localArray1[num1] = converter(array[num1]);
}
return localArray1;
}

Thanks.
 
Hi, is there a standard way of handling null with System.Array.Find methods?
For instance, currently I must do the following;

Fruit[] filterFruits = null;
if (arrayOfFruits != null)
{
filterFruits =
Array.FindAll(arrayOfFruits,
delegate(Fruit fruit)
{
// skip over apples
return (fruit.kind != Fruit.TypeOfFruit.Apple);
});
}

Is there a best practice for handling null or is the way that I am doing it
the best way; Array.FindAll throws ArgumentNullException if array is a null
reference. I looked at msdn2 site and they don't suggest any best practices
for this.

It all depends.

If you are using null to indicate "nothing in the array yet", then you
could simply change your initialization to:

Fruit[] filterFruits = new Fruit[0];

and then the special case for null disappears.

However, this depends upon interpretation. If an empty array means
something different from null (for example, if an empty array means
"filter with no fruits", while a null means "do not filter on fruits",
and the results would be different) then you really do need the test
against null, because you want to do something different in the null
case.

I tend to initialize to empty collections rather than null, unless
null and an empty collection mean logically different things.
 
Ok, I have noticed that some people here are using the method 'SomeType[]
thisVar = new SomeType[0];' I guess that so the array is empty but not null
and prevents any NullReferenceException from occuring. The string class has
'string.Empty' and since the Array class is the base class for arrays, then
maybe it would be nice to have something like Array.Empty. Then I could do
'SomeType[] thisVar = Array.Empty;' that would be nice.

I guess then that 'SomeType[] thisVar = new SomeType[0];' would be the
standard case for handling null so I can freely pass array references to
generic helper methods like Array.Find/ConvertAll etc... My only problem is
that I get my arrays back from methods, ie, 'SomeType[] thisArray = null;
someClass.getSomeArray(someConstraintParameters, out thisArray);'. I could
set thisArray to 'new SomeType[0];' but I have no guarentee that the method
will not be set it to null at some point, now or in the future if code
should get modified.

This is code that I came up with for handling this situation.

public static TOutput[] ConvertArray<TInput, TOutput>(

TInput[] array,

Converter<TInput, TOutput> converter)

{

if (array == null)

{

return (TOutput[])null;

}

else

{

return Array.ConvertAll(array, converter);

}

}

Then I would simply call this method to do conversion like this;

Converter<int, string> converter = new Converter<int, string>(IntToString);

string[] sarr = ConvertArray<int, string>(arr, converter);

I think that this is rather redundant though since the the code for
ConvertAll<TInput, TOutput> is as follows;

public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] array,

Converter<TInput, TOutput> converter)

{

if (array == null)

{

throw new ArgumentNullException("array");

}

if (converter == null)

{

throw new ArgumentNullException("converter");

}

TOutput[] localArray1 = new TOutput[array.Length];

for (int num1 = 0; num1 < array.Length; num1++)

{

localArray1[num1] = converter(array[num1]);

}

return localArray1;

}

Ya know, I can see them throwing an exception for the case when converter is
null but I wish that they returned the value '((TOutput[])null)' when
'TInput[] array' is null. I also just thought of something, I could also do
the following;

Array.ConvertAll(CheckArray<SomeType>(someArray, converter);

and define CheckArray as;

public static T[] CheckArray<T>(T[] array)

{

return array == null ? new T[0] : array;

}

that would also work too. I can't think of a good name for the method
CheckArray though.

I was also wondering is ConvertAll<> there as an convenience method or does
it perform any optimizations when copying arrays from one type array to
another? I according to msdn2, , this method is an O(n) operation, where n
is the Length of array.

Maybe I should suggest to the project team that we create a type of
NullArray<T> and somehow initialize it to T[0]. do know how though.

Thanks,

Bruce Wood said:
Hi, is there a standard way of handling null with System.Array.Find methods?
For instance, currently I must do the following;

Fruit[] filterFruits = null;
if (arrayOfFruits != null)
{
filterFruits =
Array.FindAll(arrayOfFruits,
delegate(Fruit fruit)
{
// skip over apples
return (fruit.kind != Fruit.TypeOfFruit.Apple);
});
}

Is there a best practice for handling null or is the way that I am doing it
the best way; Array.FindAll throws ArgumentNullException if array is a null
reference. I looked at msdn2 site and they don't suggest any best practices
for this.

It all depends.

If you are using null to indicate "nothing in the array yet", then you
could simply change your initialization to:

Fruit[] filterFruits = new Fruit[0];

and then the special case for null disappears.

However, this depends upon interpretation. If an empty array means
something different from null (for example, if an empty array means
"filter with no fruits", while a null means "do not filter on fruits",
and the results would be different) then you really do need the test
against null, because you want to do something different in the null
case.

I tend to initialize to empty collections rather than null, unless
null and an empty collection mean logically different things.
 
Ok, I have noticed that some people here are using the method 'SomeType[]
thisVar = new SomeType[0];' I guess that so the array is empty but not null
and prevents any NullReferenceException from occuring. The string class has
'string.Empty' and since the Array class is the base class for arrays, then
maybe it would be nice to have something like Array.Empty. Then I could do
'SomeType[] thisVar = Array.Empty;' that would be nice.

I guess then that 'SomeType[] thisVar = new SomeType[0];' would be the
standard case for handling null so I can freely pass array references to
generic helper methods like Array.Find/ConvertAll etc... My only problem is
that I get my arrays back from methods, ie, 'SomeType[] thisArray = null;
someClass.getSomeArray(someConstraintParameters, out thisArray);'. I could
set thisArray to 'new SomeType[0];' but I have no guarentee that the method
will not be set it to null at some point, now or in the future if code
should get modified.

Really, the decision of whether to use an empty array, or an empty
array _and_ null is all about semantics, not preventing exceptions.
You cited the example of a method like getSomeArray() returning null
instead of an array. That would be logical if null meant something
like, "I failed. I couldn't get any array at all," while an empty
array meant, "I got an array and it has nothing in it."

Again, if the method can return null _or_ an empty array, and say null
means "error" then of course you want to handle it separately. You
_don't_ want to go passing that null around to other methods because
the method that was supposed to get the array _failed_.

On the other hand, if the method always returns an array, just
sometimes it didn't fetch any items, then it should never return null.

Most of my methods that get collections of things return empty
collections if there is nothing to return, never null. I return null
only if the method failed and the calling application should try
another strategy, or shut down, or some other thing outside the normal
course of events.

However, what if you're using a library and some badly-behaved
function returns null to mean "I couldn't find anything" rather than
returning an empty array? Well, then you have to put a wrapper around
it to fix up its return values so that null translates to an empty
collection.

However, as I said, it's all about semantics. What does returning null
_mean_? What does returning an empty array _mean_? If they mean the
same thing, then why is the function returning null?
 
Erica said:
Ok, I have noticed that some people here are using the method 'SomeType[]
thisVar = new SomeType[0];' I guess that so the array is empty but not null
and prevents any NullReferenceException from occuring. The string class has
'string.Empty' and since the Array class is the base class for arrays, then
maybe it would be nice to have something like Array.Empty. Then I could do
'SomeType[] thisVar = Array.Empty;' that would be nice.

What exact type would Array.Empty be declared to return? You'd have to
pass in the type of the array you're interested in, at which point you
might as well just do new SomeType[0]; or new SomeType[]{}
 
Back
Top