views:

126

answers:

3

Hi,

I'm fairly new to C# programming and need some help.

I am trying to assign values I've gathered from a JSON feed to my own type, a class in which I have defined certain fields (properties) to put the JSON elements into, plus elements that are derived from a RegEx pattern matching process. This will then allow me to access the object using LINQ, as I am using a List to hold my objects.

There is a foreach loop in my code that loops for each match that my RegEx method finds. I am only interested in the parts of the JSON feed where there is a match.

So my own defined class is as such:

//simple field definition class
public class TwitterCollection
{
    public string origURL { get; set; }
    public string txtDesc { get; set; }
    public string imgURL { get; set; }
    public string userName { get; set; }
    public string createdAt { get; set; }
}

And then I want to populate List in the RegEx Matches loop:

    foreach (Match match in matches)
    {

        GroupCollection groups = match.Groups;
        var tc = new List<TwitterCollection>()
        {
            origURL = groups[0].Value.ToString(),
            txtDesc = res.text,
            imgUrl = res.profile_image_url,
            userName = res.from_user_id,
            createdAt = res.created_at,

        };
    }

The code will then go on to extract and sort the results via Linq to Objects. But compiler won't actually let me create my var tc = new List<TwitterCollection>() because: 'System.Collections.Generic.List' does not contain a definition for 'origURL' ... even though I have defined it.

It does not flag an error if I simply write new TwitterCollection but then how do I refer to this in my Linq expression later on??

Please help!

+5  A: 

You need to instantiate the list outside the loop:

var list = new List<TwitterCollection>();
foreach (Match match in matches)
{

    GroupCollection groups = match.Groups;
    var tc = new TwitterCollection
    {
        origURL = groups[0].Value.ToString(),
        txtDesc = res.text,
        imgUrl = res.profile_image_url,
        userName = res.from_user_id,
        createdAt = res.created_at,
    };
    list.Add(tc);
}

At the moment, you are trying to create a new list for each element. The actual compilation error is because your object initialiser is for a TwitterCollection object, not a list of them, but there's no point fixing that with this flaw in the logic anyway.

David M
Many thanks, the error is gone... but... my results on the actual web page only have the name TwitterCollection for every single URL! Any idea why this might be? Much appreciated!!
AlexW
You'll need to override the ToString method within your Group class and have it return the value that you want. By default, the ToString method will always return the fully qualified name of the class.
MattK
@Matt - It's not the OP's Group class - it's a regex group!
David M
@Alex - Oops...I read too quickly. I don't think you even need the ToString method since the Value is the captured substring isn't it?
MattK
+3  A: 

The problem is you are trying to use an object initializer to for a TwitterCollection object but you're applying it to a List<TwitterCollection>. What you want to do instead is pre-create the list and call Add instead of recreating it every time.

var list = new List<TwitterCollection>();
foreach (Match match in matches)
{

    GroupCollection groups = match.Groups;
    var tc = new TwitterCollection()
    {
        origURL = groups[0].Value.ToString(),
        txtDesc = res.text,
        imgUrl = res.profile_image_url,
        userName = res.from_user_id,
        createdAt = res.created_at,

    };
    list.Add(tc);
}

Or if you want just a LINQ query

var list = matches
  .Cast<Match>()
  .Select(x => new TwitterCollection() {
            origURL = x.Groups[0].Value.ToString(),
            txtDesc = res.text,
            imgUrl = res.profile_image_url,
            userName = res.from_user_id,
            createdAt = res.created_at } )
  .ToList();
JaredPar
+2  A: 

Off-topic, but since you mentioned you're new to C#, I thought I'd mention that you should consider following Microsoft's naming guidelines:

http://msdn.microsoft.com/en-us/library/fzcth91k%28VS.71%29.aspx

Your class declaration would become:

public class TwitterCollection
{
    public string OrignalUrl { get; set; }
    public string TextDescription { get; set; }
    public string ImageUrl { get; set; }
    public string UserName { get; set; }
    public string CreatedAt { get; set; }
}

Another thing not outlined in the link provided is that, in most cases, Hungarian notation (txtDesc, for example) should only be used in a select few cases. Also consider not using abbreviations unless it's accepted nomenclature (e.g, Url) as there is generally no cost associated with using the complete word rather than the abbreviation.

Hope this is useful!

Ian P