so I have a generic function that calls a web service and converts it to whatever type you call the function with. However if you call CallUrl<SomeValue[]> - I don't want to return null, I want to return an empty list. I'm currently returning DefaultOrEmpty() - where that looks like:
private static T DefaultOrEmpty<T>()
{
return typeof(T).IsArray
? (T)(object)Array.CreateInstance(typeof(T).GetElementType()!, 0)
: default;
}
which works, but seems ridiculously complicated - is there a cleaner way to write this function?
CodePudding user response:
Assuming by "collection", you mean an array, specifically, I don't see anything particularly wrong with your array initialization as it's perfectly understandable, but here's a slightly shorter method if that's what you're aiming for:
private static T DefaultOrEmpty<T>()
{
return typeof(T).IsArray
? (T)Activator.CreateInstance(typeof(T), 0)
: default;
}
Or to support multidimensional arrays (which were not supported in the original method):
private static T DefaultOrEmpty<T>()
{
if (typeof(T).IsArray)
{
var args = Enumerable.Repeat(0, typeof(T).GetArrayRank())
.Cast<object>()
.ToArray();
return (T)Activator.CreateInstance(typeof(T), args);
}
return default;
}
CodePudding user response:
This is simple enough to just inline.
T[] DefaultOrEmpty<T>()
=> Array.Empty<T>();
Your current code seems to be expecting an array type parameter and then returning an array, and otherwise returning a simple value. That looks weird.
When you pass a TReference[] you will get back a TReference[]
When you pass a TReference you will get back a null rather than empty array.
When you pass a TValue[] you will get back a TValue[].
When you pass a TValue you will get back a TValue (like 0) rather than null or empty.
That may be your intent, it's just quite unusual to pass an array type generic parameter.