foreach statement cannot operate on variables of type 'object'

31,156

Solution 1

If you do not know the exact type of object, but you know for sure that whatever it is, it will have GetEnumerator on it (say, because it's a collection or one of your own objects that implements IEnumerable) you can stop the compiler from issuing an error by casting to dynamic, like this:

foreach (var item in (dynamic)(ddlOther.DataSource)) {
    ...
}

The trade-of here is that if it turns out that ddlOther.DataSource does not have GetEnumerator, you will get an error at runtime, rather than a compile-time error.

Solution 2

Modify your code to check on the IEnumerable interface. It have the feeling underlying correction is more what you want.

public void DataSource(object source, object select, string Value = "UId", string Text = "Text")
{
    ddlThis.DataSource = source;
    ddlThis.DataTextField = Text;
    ddlThis.DataValueField = Value;
    ddlThis.DataBind();

    ddlThisHidden.DataSource = source;
    ddlThisHidden.DataTextField = Text;
    ddlThisHidden.DataValueField = Value;
    ddlThisHidden.DataBind();

    if (select != null)
    {
        ddlOther.DataSource = select;
        ddlOther.DataTextField = Text;
        ddlOther.DataValueField = Value;
        ddlOther.DataBind();

        if (select is IEnumerable) //check if the object is a list of objects
            foreach (var item in (IEnumerable)ddlOther.DataSource)
                ddlThis.Items.Remove(item);
        else //try to remove the single object
            ddlThis.Items.Remove(select)
    }
}
Share:
31,156
Mert
Author by

Mert

Updated on March 27, 2020

Comments

  • Mert
    Mert about 4 years

    I have 3 dropdownlist 2 with same source, 3rd with selected list. and if selected list not null I should remove selecteds from first one, and bind in 3rd one. second is static that shows orginal list.

    but I couldn't figure out how to foreach in an object.

    ERROR : foreach statement cannot operate on variables of type 'object' because 'object' does not contain a public definition for 'GetEnumerator'

        public void DataSource(object source, object select, string Value = "UId", string Text = "Text")
        {
            ddlThis.DataSource = source;
            ddlThis.DataTextField = Text;
            ddlThis.DataValueField = Value;
            ddlThis.DataBind();
    
            ddlThisHidden.DataSource = source;
            ddlThisHidden.DataTextField = Text;
            ddlThisHidden.DataValueField = Value;
            ddlThisHidden.DataBind();
    
            if (select != null)
            {
                ddlOther.DataSource = select;
                ddlOther.DataTextField = Text;
                ddlOther.DataValueField = Value;
                ddlOther.DataBind();
    
                foreach (var item in ddlOther.DataSource)
                    ddlThis.Items.Remove(item);
            }
        }
    

    VERSION 2

        public void DataSource(IList source, IList select, string Value = "UId", string Text = "Text")
        {
            ddlThis.DataSource = source;
            ddlThis.DataTextField = Text;
            ddlThis.DataValueField = Value;
            ddlThis.DataBind();
    
            ddlThisHidden.DataSource = source;
            ddlThisHidden.DataTextField = Text;
            ddlThisHidden.DataValueField = Value;
            ddlThisHidden.DataBind();
    
            if (select != null)
            {
                ddlOther.DataSource = source.Cast<object>()
                    .Select(x => select.Cast<object>().Any(c=> c.GetType().GetProperty(Value).GetValue(source, null).ToString() == x.GetType().GetProperty(Value).GetValue(source, null).ToString()));
                ddlOther.DataTextField = Text;
                ddlOther.DataValueField = Value;
                ddlOther.DataBind();
    
                foreach (var item in select)
                    ddlThis.Items.Remove(item.ToString());
            }
        }
    

    VERSION 3 WORKING!

        public void DataSource(object source, object select, string Value = "UId", string Text = "Text")
        {
            ddlThis.DataSource = source;
            ddlThis.DataTextField = Text;
            ddlThis.DataValueField = Value;
            ddlThis.DataBind();
    
            ddlThisHidden.DataSource = source;
            ddlThisHidden.DataTextField = Text;
            ddlThisHidden.DataValueField = Value;
            ddlThisHidden.DataBind();
    
            if (select != null)
            {
                ddlOther.DataSource = ((IEnumerable)source).Cast<dynamic>().ToList().FindAll(x => ((IEnumerable)select).Cast<dynamic>()
                    .Any(c => c.GetType().GetProperty(Value).GetValue(c, null) == x.GetType().GetProperty(Value).GetValue(x, null)));
    
                ddlOther.DataTextField = Text;
                ddlOther.DataValueField = Value;
                ddlOther.DataBind();
    
                foreach (var item in (dynamic)(ddlOther.DataSource))
                    ddlThis.Items.Remove(item.ToString());
            }
        }
    
  • juharr
    juharr over 9 years
    That's not going to fix the compilation error since the code that is trying to foreach on an object is still present.
  • Jessica
    Jessica over 9 years
    Forgot the cast ... sry... edited
  • Mert
    Mert over 9 years
    yes dynamic solved my problem! just I have last small question ddlOther.DataSource = ((IEnumerable)source).Cast<dynamic>().ToList().FindAll(x => ((IEnumerable)select).Cast<dynamic>().Any(c => c.UId == x.UId)); in this code I gave "UId" manually but I want to give property name dynamically can I do that? something like .Any(c => c[Value] == x[Value]));
  • Mert
    Mert over 9 years
    you can check in the question at version 3. easier to read.
  • Sergey Kalinichenko
    Sergey Kalinichenko over 9 years
    @Mert Unfortunately, passing property names as string is not possible simply with dynamic. You would need to make a method that goes through reflection or through Linq.Expressions to do that.
  • Mert
    Mert over 9 years
    yeah I just did it with reflection! thank you very much