bflemi3
bflemi3

Reputation: 6790

Cast array of objects to a different array of objects

I am pulling back information about locations from a webservice. The service returns an array of WebObjectsDTOs which holds all of the objects. The objects can be of different types but in this case I'm requesting only objects of type MlaLocation. I then need to orderby the locations name. The problem I ran into was that I cannot do an orderby on searchResult.WebObjectDTOs because it's the base object and does not have access to the location name.

I thought my solution would be to cast searchResult.WebObjectDTOs to MlaLocationDTO[] since searchResult is only returning an array of MlaLocationDTO. But what I'm seeing in debug is that mlaLocations is being set as null even though searchResult.WebObjectDTOs has objects in it.

MlaWebObjectServiceClient svc = new MlaWebObjectServiceClient();
SearchRequest searchRequest = new SearchRequest(){
    OperatingCompanyId = Guid.Parse("e4be5383-03d0-4a99-9613-6238dd2396ad"), 
    WebObjectType = "MlaLocation"
};
SearchResult searchResult = svc.GetMlaWebObjects(searchRequest);
MlaLocationDTO[] mlaLocations = searchResult.WebObjectDTOs as MlaLocationDTO[];
rptLocationsList.DataSource = mlaLocations.OrderBy(m => m.Name);
rptLocationsList.DataBind();

Upvotes: 2

Views: 214

Answers (7)

Anthony Pegram
Anthony Pegram

Reputation: 126804

You are not able to perform this cast because, in this case, the array of WebObjectDTO is not an array of MlaLocationDTO. Consider a simpler example, assume you have

class Alpha { }
class Beta : Alpha { } 

Alpha[] alphas = new Beta[10]; // supported via array variance
Beta[] betas = (Beta[])alphas; // legal cast, the array is actually of this type

Alpha[] alphas2 = new Alpha[10];
Beta[] betas2 = (Beta[])alphas2; // not legal, the array isn't of this type

Each element in the array could very well be an MlaLocationDTO, but unless the array itself is an array of these objects, you cannot perform this cast. It will blow up at runtime, as you have seen in your code.

As for solutions, if MlaLocationDTO has an inheritance relationship with WebObjectDTO where MlaLocationDTO : WebObjectDTO and if each object in the array is in fact a MlaLocationDTO, you can cast each individual element.

var locations = searchResult.WebObjectDTOs.Cast<MlaLocationDTO>();

However, if the locations are not truly this type of object, then you'll just need to define the conversion yourself. It is simple enough to do this in query form.

var locations = from location in searchResult.WebObjectDTOs
                select new MlaLocationDTO
                {
                    Name = ...,
                    Id = ...,
                    /* etc. */
                };

Optionally include .ToArray() on either of the query forms if you need an array result. The type would then be MlaLocationDTO[]. Sans the ToArray() invocation, it would simply be IEnumerable<MlaLocationDTO>.

Upvotes: 1

Azhar Khorasany
Azhar Khorasany

Reputation: 2709

Have you tried looping through the WebObjectDTOs and adding values to mlaLocations: May be:

 for(int objIndex = 0; objIndex <= WebObjectDTOs.Count - 1; objIndex++)
 {
      mlaLocations[objIndex].Add(WebObjectDTOs[objIndex]);
 }

or something similar?

Upvotes: 0

Kinexus
Kinexus

Reputation: 12904

You should be able to cast your array to the type;

var mlaLocations = searchResult.WebObjectDTOs.Cast<MlaLocationDTO>();

See Enumerable.Cast Method

Upvotes: 1

tomfanning
tomfanning

Reputation: 9660

How about:

IEnumerable<MlaLocationDTO> castedResults = searchResult.WebObjectDTOs.Cast<MlaLocationDTO>();

Upvotes: 0

Sergii Kudriavtsev
Sergii Kudriavtsev

Reputation: 10487

Instead of

MlaLocationDTO[] mlaLocations = searchResult.WebObjectDTOs as MlaLocationDTO[];

try this:

MlaLocationDTO[] mlaLocations = searchResult.WebObjectDTOs.Cast<MlaLocationDTO>().ToArray();

Upvotes: 0

Ahmad Mageed
Ahmad Mageed

Reputation: 96477

Since your collection has many other types of objects, you can safely filter MlaLocationDTO objects using the OfType method:

var mlaLocations = searchResult.WebObjectDTOs.OfType<MlaLocationDTO>();

If all of the objects were MlaLocationDTO, you can use the Cast method instead:

var mlaLocations = searchResult.WebObjectDTOs.Cast<MlaLocationDTO>();

Upvotes: 0

Pieter
Pieter

Reputation: 3399

You could use LINQ to do that:

searchResult.WebObjectDTOs.Select(d => d as MlaLocationDTO).ToArray();

Upvotes: 0

Related Questions