foreach语句不能对'object'类型的变量进行操作

时间:2014-12-11 16:25:18

标签: c# linq foreach

我有3个具有相同来源的下拉列表2,第3个具有所选列表。如果选择列表不为null,我应该从第一个中删除选定项,并在第三个中绑定。第二个是静态的,显示原始列表。

但是我无法弄清楚如何在一个物体中前进。

  

错误:foreach语句无法对'object'类型的变量进行操作   因为'object'不包含公共定义   '的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);
        }
    }

版本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());
        }
    }

版本3 工作!

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

2 个答案:

答案 0 :(得分:19)

如果您不知道对象的确切类型,但您确定无论它是什么,它都会有GetEnumerator(例如,因为它是一个集合或您自己的一个对象实现IEnumerable)你可以通过强制转换为dynamic来阻止编译器发出错误,如下所示:

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

这里的交易是,如果事实证明ddlOther.DataSource没有GetEnumerator,则会在运行时收到错误,而不是编译时错误。

答案 1 :(得分:0)

修改代码以检查IEnumerable接口。它有根深蒂固的感觉更多你想要的东西。

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)
    }
}