How can I do this if GetCategories is returning, and must return, a Object array.
You can't. Object
is devoid of the necessary type information, so you must resort to either reflection or casting to an explicit (non-anonymous) type.
As we can't use an implicit type (var
) in method signatures in C# (unlike in C++ where you can use auto
) we must either use a Value-Tuple (a C# 7.2 feature) or manually define your object type.
C# 7.2 Value-Tuple:
public static (Int32 id, String name)[] GetCategories()
{
return new[]
{
( 1, "A" ),
( 2, "BA" ),
( 3, "BAC" ),
};
}
Manual type:
public class /* or struct */ Category
{
public Category( Int32 id, String name )
{
this.Id = id;
this.Name = name;
}
public Int32 Id { get; }
public String Name { get; }
}
public static Category[] GetCategories()
{
return new[]
{
new Category( 1, "A" ),
new Category( 2, "BA" ),
new Category( 3, "BAC" ),
};
}
You said the method's signature must return Object[]
, but if we return a value-tuple or custom type then we can still cast to it, albiet without compile-time type safety:
public Object[] GetCategories()
{
return new[]
{
new Category( 1, "A" ),
new Category( 2, "BA" ),
new Category( 3, "BAC" ),
};
}
IEnumerable DoSomething()
{
return this.GetCategories()
.Cast<Category>()
.Where( c => c.Name.Contains("A") )
}
Or:
public Object[] GetCategories()
{
return new (Int32 id, String name)[]
{
new ( 1, "A" ),
new ( 2, "BA" ),
new ( 3, "BAC" ),
};
}
IEnumerable DoSomething()
{
return this.GetCategories()
.Cast<(Int32 id, String name)>()
.Where( c => c.Name.Contains("A") )
}
In my opinion we should always prefer Value-Tuples over anonymous types anyway, they have numerous advantages over C#'s anonymous types:
- You can use them in method signatures as return types or parameter types.
- They're immutable.
- They're value-types (not heap-allocated objects) which avoids unnecessary allocation.
- You can use them whenever you'd use anonymous types.
The only downside is opening yourself up to a Lilliputian war about whether value-tuple members should be PascalCase
or camelCase
.
BTW, if your data is immutable then you should return a static readonly IReadOnlyList[]
instead of return new[]...
to avoid extraneous unnecessary heap allocations on every call and to prevent unwanted mutation of static state:
private static readonly IReadOnlyList[] _categories = new[]
{
...
};
public static IReadOnlyList[] GetCategories() => _categories;