foreach statement cannot operate on variables of type 'object'
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)
}
}
Mert
Updated on March 27, 2020Comments
-
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 over 9 yearsThat's not going to fix the compilation error since the code that is trying to
foreach
on anobject
is still present. -
Jessica over 9 yearsForgot the cast ... sry... edited
-
Mert over 9 yearsyes 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 over 9 yearsyou can check in the question at version 3. easier to read.
-
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 over 9 yearsyeah I just did it with reflection! thank you very much