2

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();
4
  • 1
    Array casting is odd in C#, and, as far as I know, you must iterate through each of the items in the array and cast them directly into the new array. Commented Dec 6, 2011 at 15:46
  • @RichardJ.RossIII you don't need to iterate. See the link in my answer. For example, object[] a = new string[] { "a", "b", "c" } is legal. Commented Dec 6, 2011 at 15:53
  • @phoog correct downwards casting is fine, but upwards casting is different, in that it will not implicitly work. Commented Dec 6, 2011 at 15:55
  • @RichardJ.RossIII you're right in this case. However, it's not the upcast per se; it depends on the actual runtime type of the array. This was the source of my confusion. This is fine: object[] a = new string[] { "a", "b", "c" }; string[] b = (string[])a; But this is not: object[] a = new object[] { "a", "b", "c" }; string[] b = (string[])a; Commented Dec 6, 2011 at 16:44

7 Answers 7

1

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

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

See Enumerable.Cast Method

Sign up to request clarification or add additional context in comments.

Comments

1

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>.

Comments

0

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>();

Comments

0

You could use LINQ to do that:

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

Comments

0

Instead of

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

try this:

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

Comments

0

How about:

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

Comments

0

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?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.