开发者

C# foreach error

string connection = "Data Source=" + server + ";Initial Catalog=" + dbase + 
";User ID=" + userid + ";Password=" + password;

conn = new SqlConnection(connection);
conn.Open();
SqlCommand cmd = new SqlCommand("SUBNETTEMP", conn);
cmd.CommandType = CommandType.StoredProcedure;

Parameters d = new Parameters();
d.addparam(15, 1);
d.addparam(15, 2);

foreach (var param in d)
{
    cmd.Parameters.Add(new SqlParameter(param.Key, param.Value));
} 

There's a class called parameters:

class Parameters
{
    Dictionary<int, int> paramids;
    public Dictionary<int, int> addparam(int sid, int sbid)
    {
        if (paramids == null)
       开发者_如何转开发     paramids = new Dictionary<int, int>();
        paramids.Add(sid, sbid);
        return paramids;
    }
}

I am not sure why I am getting error :"foreach statement cannot operate on variables of type 'ConsoleApplication1.Parameters' because 'ConsoleApplication1.Parameter' doesnot contain public definition for GetEnumerator.


Your Parameters class has no GetEnumerator method. Just like the error said.

You can either iterate over the paramids field, but for that you'd need to publicly expose it, which is a bad idea IMO.

The alternative is implementing GetEnumerator, forwarding it to paramids.GetEnumerator:

public IEnumerator<KeyValuePair<int,int>> GetEnumerator()
{
    return paramids.GetEnumerator();
}

For good measure you should also add and implement the IEnumerable<KeyValuePair<int,int>> and IEnumerable interfaces, even if they're not necessary for a simple foreach.


As a side-note: I consider exposing the internal dictionary as the return value of addparam a dubious design choice. If you want a fluent API return your own instance of Parameters, and not the internal dictionary. I.e. use return this.

Also I'd use the .net naming conventions, so call your method AddParam not addparam.


So your complete class would be:

class Parameters:IEnumerable<KeyValuePair<int,int>>
{
    Dictionary<int, int> paramids;

    public Parameters AddParam(int sid, int sbid)
    {
        if (paramids == null)
            paramids = new Dictionary<int, int>();
        paramids.Add(sid, sbid);
        return this;
    }

    public IEnumerator<KeyValuePair<int,int>> GetEnumerator()
    {
        return paramids.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}


Your Parameters class would need to either inherit from Dictionary, or expose its inner dictionary to enumerate via foreach:

class Parameters {
    Dictionary<int, int> paramids;
    ....
    public Dictionary<int, int> ParamIDs {
        get { return paramids; }
    }
}

So now this would work:

foreach (var param in d.ParamIDs) {
....
}


If you want to use your Parameters class as dictionary - inherit it from Dictionary<int, int>:

class Parameters: Dictionary<int, int>
{
}

but in this case maybe better to use just Dictionary<int, int>


Parameters does not have a GetEnumerator()? method, which is what foreach relies on for looping over a collection. You should refactor out the Parameters class (it looks a bit over-crafted to have a separate class for that) and use a Dictionary<> directly.

An alternative is to have Parameters implement GetEnumerator():

class Parameters
{
    Dictionary<int, int> paramids;
    public Dictionary<int, int> addparam(int sid, int sbid)
    {
        if (paramids == null)
            paramids = new Dictionary<int, int>();
        paramids.Add(sid, sbid);
        return paramids;
    }

    public IEnumerator<KeyValuePair<int, int>> GetEnumerator() 
    { 
        return paramids.GetEnumerator(); 
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜