Mikey
Mikey

Reputation: 15

Casting an object inside join statement

Want to concatenate all the items that are selected in my ListBox (SelectedItems). The list box is using a class (RegionModel) as a datadource.

I have this going in foreach loop, but I'd like to put this into a single line, if possible. What I have doesn't break, but it doesn't print, just the class name that the item represents.

namespace ProLimb.Models
{
    public class RegionModel
    {
        public string Continent { get; set; }
        public string Country { get; set; }
    }

    //TRYING TO GET TO WORK
    Regions = string.Join("; ", lstRegions.SelectedItems.OfType<object>());
}

I figure I need to cast it, it doesn't seem to work.

The final output should look like: "North; East; South; West", but instead it comes out: ProLimb.Forms.RegionModel

Upvotes: 1

Views: 292

Answers (4)

Gabriel Llorico
Gabriel Llorico

Reputation: 1803

two answers can solve your problem stated by Mong Zhu and Ehsan Sajjad

all you need to show us is which property you want to contain/display Continent or Country

or my answer which is reflection if you dont want to overwrite your ToString()

PropertyYouWantToShow is either Continent or Country

Regions = string.Join("; ", lstRegions.SelectedItems.OfType<object>()
                .Select(c => c.GetType()
                              .GetProperty("PropertyYouWantToShow") //will get property
                              .GetValue(c))); //will get values listed on PropertyYouWantToShow

or you could cast it in your selectas per Richard Barker but still add OfType<object>

Regions = string.Join("; ", lstRegions.SelectedItems.OfType<object>()
                .Select(c => ((RegionModel)c).PropertyYouWantToShow)); // either Country or Continent

or you could directly cast it in your OfType

Regions = string.Join("; ", lstRegions.SelectedItems.OfType<RegionModel>()
                .Select(c => c.PropertyYouWantToShow));

Upvotes: 1

Marco Salerno
Marco Salerno

Reputation: 5201

This way:

namespace ProLimb.Models
{
    public class RegionModel
    {
        public string Continent { get; set; }
        public string Country { get; set; }
    }

    //TRYING TO GET TO WORK
    Regions = string.Join("; ", lstRegions.SelectedItems.OfType<RegionModel>().Select(x => x.Continent));
}

You were trying to concatenate your objects but they aren't string, so you have to ask for the property you need.

Upvotes: 0

pneuma
pneuma

Reputation: 977

You probably want to Cast() your entities. As far as I understand, SelectedItems is not a generic collection but still implements IEnumerable. If you want to use LINQ on it, you have two options:

  • If you know for sure collection only has items of certain type, you have to use Cast<T>() on a collection to transform IEnumerable into IEnumerable<T>.
  • If you're not sure what type of items are present in the collection, and only want to deal with items of a particular type ignoring all the others, you need to use OfType<T>(), yielding IEnumerable<T> that only contains objects of the specified type.

Try this:

Regions = string.Join("; ", lstRegions.SelectedItems.Cast<RegionModel>().Select(x => x.Country));

This would also work:

Regions = string.Join("; ", lstRegions.SelectedItems.OfType<RegionModel>().Select(x => x.Country));

Whether the latter is more preferable in your scenario is up to your programming style, but I recommend the first version. That way if the collection contains items of unexpected type, you won't ignore it and fail fast, which is preferable.

Upvotes: 0

Ehsan Sajjad
Ehsan Sajjad

Reputation: 62498

You can override the ToString() method for your class and then just call it in a linq select:

public class RegionModel
{
    public string Continent { get; set; }
    public string Country { get; set; }

    public override String ToString()
    {
       return $"{Country},{Continent}";
    }
}

and then :

string.Join("; ", lstRegions.SelectedItems);

The above is just an example to show how ToString() can be used here but you might need to return either only Country or Continent as per your need.

Upvotes: 0

Related Questions