由于其保护级别,LINQ匿名对象无法访问

时间:2015-03-13 01:50:14

标签: c# linq .net-4.5 anonymous-types

我有LINQ逻辑,它将正则表达式解析的数据收集到动态创建的字典中。我面临的问题是访问字典中的数据(Info)。

Regex
    .Matches(text, pattern,
        RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture) 
    .OfType<Match>()    
    .Select(mt => new
    {
        Info = mt.Groups["ADKey"].Captures
            .OfType<Capture>()
            .Select(cp => cp.Value)
            .Zip(mt.Groups["ADValue"].Captures.OfType<Capture>().Select(cp => cp.Value),
                (k, v) => new { key = k, value = v })
            .ToDictionary(cp => cp.key, cp => cp.value),
        Nodes = mt.Groups["Key"].Captures
            .OfType<Capture>()
            .Select(cp => cp.Value)
            .Zip(mt.Groups["Value"].Captures.OfType<Capture>().Select(cp => cp.Value),
                (k, v) => new { key = k, value = v })
            .ToDictionary(cp => cp.key, cp => cp.value),
    });

List<string> myInfo = new List<string>();
myInfo = Info.Keys.ToList();

当我尝试访问字典(info)时,在转换为列表时,我收到的错误是&#34;信息&#34;由于其保护级别而无法访问。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

我遇到了类似的错误:由于其保护级别,EnumerableExtensions.Join(IEnumerable,string)'无法访问。然后意识到我忘了在代码中包含使用System.Linq;

答案 1 :(得分:0)

您当前正在创建一个匿名类型列表,这些类型具有单个属性Info,即Dictionary<string, string>。您似乎没有在变量中捕获结果。然后,您尝试访问Info,就好像它是RegEx查询之外的单个对象一样。这两个Info引用了不同的东西。

我给你的第一个建议是改变你的代码:

IEnumerable<Dictionary<string, string>> query =
    Regex
        .Matches(
            text,
            pattern,
            RegexOptions.IgnorePatternWhitespace
                | RegexOptions.ExplicitCapture) 
        .OfType<Match>()
        .Select(mt => mt.Groups["Key"].Captures
                .OfType<Capture>()
                .Select(cp => cp.Value)
                .Zip(
                    mt.Groups["Value"].Captures
                        .OfType<Capture>()
                        .Select(cp => cp.Value),
                    (k, v) => new
                    {
                        key = k,
                        value = v
                    })
                .ToDictionary(cp => cp.key, cp => cp.value));

现在,我不相信你想要一个IEnumerable<Dictionary<string, string>>,因为在接下来的两行中你似乎想要直接从结果中拉出键。

看起来你可能想要这个:

Dictionary<string, string> query =
    Regex
        .Matches(text, pattern,
            RegexOptions.IgnorePatternWhitespace
                | RegexOptions.ExplicitCapture) 
        .OfType<Match>()
        .SelectMany(mt => mt.Groups["Key"].Captures
            .OfType<Capture>()
            .Select(cp => cp.Value)
            .Zip(
                mt.Groups["Value"].Captures
                    .OfType<Capture>()
                    .Select(cp => cp.Value),
                (k, v) => new
                {
                    key = k,
                    value = v
                }))
        .ToDictionary(cp => cp.key, cp => cp.value);

但我怀疑这会发生重大冲突。

我想你可能想要这样的东西:

Match match = Regex.Match(text, pattern,
    RegexOptions.IgnorePatternWhitespace
        | RegexOptions.ExplicitCapture);

Dictionary<string, string> result =
    match
        .Groups["Key"]
        .Captures
        .OfType<Capture>()
        .Select(cp => cp.Value)
        .Zip(
            match.Groups["Value"].Captures
                .OfType<Capture>()
                .Select(cp => cp.Value),
            (k, v) => new
            {
                key = k,
                value = v
            })
        .ToDictionary(cp => cp.key, cp => cp.value);

然后你可以这样做:

    List<string> myInfo = result.Keys.ToList();

鉴于您的更新问题,在我看来您可能想要这个:

Match match =
    Regex.Match(text, pattern,
        RegexOptions.IgnorePatternWhitespace
            | RegexOptions.ExplicitCapture);

var result = new
{
    Info = match.Groups["ADKey"].Captures
        .OfType<Capture>()
        .Select(cp => cp.Value)
        .Zip(match.Groups["ADValue"].Captures.OfType<Capture>().Select(cp => cp.Value),
            (k, v) => new { key = k, value = v })
        .ToDictionary(cp => cp.key, cp => cp.value),
    Nodes = match.Groups["Key"].Captures
        .OfType<Capture>()
        .Select(cp => cp.Value)
        .Zip(match.Groups["Value"].Captures.OfType<Capture>().Select(cp => cp.Value),
            (k, v) => new { key = k, value = v })
        .ToDictionary(cp => cp.key, cp => cp.value),
};

List<string> myInfo = result.Info.Keys.ToList();