在模式匹配后使用foreach循环填充List<T>

5

我是一个相对新手的C#编程者,需要一些帮助。

我正在尝试将我从JSON源获取的值分配给我的自定义类型,这个类型是一个类,其中我已经定义了某些字段(属性)来存储JSON元素,以及从正则表达式匹配过程中得出的元素。这将允许我使用LINQ访问对象,因为我正在使用List来保存我的对象。

我的代码中有一个foreach循环,循环遍历我的正则表达式方法找到的每个匹配项。我只对JSON源中有匹配项的部分感兴趣。

所以,我的自定义类如下:

//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; }
}

然后我想在正则表达式匹配循环中填充列表:

    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,

        };
    }

代码将继续通过Linq to Objects提取和排序结果。但编译器实际上不允许我创建var tc = new List<TwitterCollection>(),因为:'System.Collections.Generic.List'不包含“origURL”的定义……即使我已经定义了它。
如果我只写new TwitterCollection,它不会标记错误,但是我如何在稍后的Linq表达式中引用它呢?
请帮忙!

你为什么使用JSON API?为什么不用XML? - Daniel A. White
JSON开销小(显然)?问题是……我已经使用了下面提供的解决方案,但为什么现在它到处都在说TwitterCollection……???看起来非常奇怪。 - Alex
3个回答

10

你需要在循环外部实例化列表:

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

目前,您正在尝试为每个元素创建一个新列表。实际编译错误是因为您的对象初始化器是针对TwitterCollection对象而不是它们的列表,但是在逻辑上存在这种缺陷的情况下,修复这个问题是没有意义的。


非常感谢,错误已经消失了...但是...我的实际网页结果中每个URL都只有名称TwitterCollection!你有什么想法吗?非常感谢!! - Alex
你需要在你的Group类中重写ToString方法,并让它返回你想要的值。默认情况下,ToString方法将始终返回类的完全限定名称。 - Kwal
@Matt - 这不是 OP 的 Group 类 - 它是一个正则表达式组! - David M
@Alex - 哎呀...我读得太快了。你甚至不需要ToString方法,因为Value就是捕获的子字符串,对吧? - Kwal

3
问题在于您试图使用对象初始化程序来创建一个TwitterCollection对象,但是您正在将其应用于List<TwitterCollection>。相反,您想要预先创建列表并调用Add而不是每次重新创建它。
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);
}

或者如果您只想要一个LINQ查询

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

2

虽然题外话,但是因为你提到你是C#新手,我想提醒你应该考虑遵循微软的命名规范:

http://msdn.microsoft.com/zh-cn/library/fzcth91k.aspx

你的类声明将变成:

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

链接中未提到的另一件事是,在大多数情况下,匈牙利命名法(例如txtDesc)应仅在少数情况下使用。此外,请考虑不使用缩写,除非它是公认的术语(例如Url),因为通常使用完整单词而不是缩写没有任何成本。

希望这对您有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接