对于使用publicsuffix.org的域名解析器代码,将降级Linq转换为普通C#.NET 2.0

对于使用publicsuffix.org的域名解析器代码,将降级Linq转换为普通C#.NET 2.0,linq,url,dns,subdomain,converter,Linq,Url,Dns,Subdomain,Converter,基于这个答案,我尝试使用code.google.com/p/domainname-parser/,它将使用publicsuffix.org中的publicsuffix列表来获取管理我的cookie集合的子域和域 目前,Domainname解析器是我在internet上找到的唯一实现publicsuffix.org列表的.NET代码 为了使用域名解析器,我想对源代码进行更改,以便它能够: 在.NET2.0中使用 接受Uri对象以将主机解析为子域、域和TLD 如果LastModified发生更改,将

基于这个答案,我尝试使用code.google.com/p/domainname-parser/,它将使用publicsuffix.org中的publicsuffix列表来获取管理我的cookie集合的子域和域

目前,Domainname解析器是我在internet上找到的唯一实现publicsuffix.org列表的.NET代码

为了使用域名解析器,我想对源代码进行更改,以便它能够:

  • 在.NET2.0中使用
  • 接受Uri对象以将主机解析为子域、域和TLD
  • 如果LastModified发生更改,将使用WebRequest和WebResponse从publicsuffix.org自动下载最新列表
  • 因此,它将变得更有用,并且总是更新。(2) (3)不是问题,但(1)是我现在的重点

    当前的域名解析器是v1.0,构建为使用.NET3.5,在代码中使用Linq。为了使其与.NET2.0兼容,我需要将Linq代码转换为非Linq代码,这使我能够理解公共后缀列表规则。这是正常、通配符和例外规则。但是,我不知道Linq以及如何将其转换回正常方式

    转换器工具可能很有用,但最好是我逐行检查和修改它

    现在我的问题是如何转换它?例如,来自DomainNames类中FindMatchingLDRule方法的代码:

    //  Try to match an wildcard rule:
    var wildcardresults = from test in TLDRulesCache.Instance.TLDRuleList
                          where
                            test.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                            &&
                            test.Type == TLDRule.RuleType.Wildcard
                          select
                            test;
    
    还有:

            var results = from match in ruleMatches
                          orderby match.Name.Length descending
                          select match;
    
    遵循的简单指导原则是什么? 或者使用任何免费工具将上面这句话转换成.NET2.0中的普通C代码

    我相信,没有数据库参与,只是在他们处理收集的方式

    我还试图联系域名解析器所有者以改进代码并帮助我解决这个问题

    谢谢


    Callmelan

    好的,作为对评论的回应,下面是一个返回列表的版本

    public List<TLDRule> MatchWildcards(IEnumerable<TLDRule> rules,
                                        string checkAgainst)
    {
        List<TLDRule> ret = new List<TLDRule>();
        foreach (TLDRule rule in rules)
        {
            if (rule.Name.Equals(checkAgainst, 
                                 StringComparison.InvariantCultureIgnoreCase)
                && rule.Type == TLDRule.RuleType.Wildcard)
            {
                ret.Add(rule);
            }
        }
        return ret;
    }
    
    Then:
    
    List<TLDRule> wildcardresults = MatchWildcards(
        TLDRulesCache.Instance.TLDRuleList, checkAgainst);
    
    公共列表匹配通配符(IEnumerable规则,
    字符串检查(对照)
    {
    List ret=新列表();
    foreach(规则中的TLDRule规则)
    {
    如果(rule.Name.Equals)(对照,
    StringComparison.InvariantCultureInogoreCase)
    &&rule.Type==TLDRule.RuleType.Wildcard)
    {
    ret.Add(规则);
    }
    }
    返回ret;
    }
    然后:
    列出通配符结果=匹配通配符(
    TldruleCache.Instance.TLDRuleList,对照检查);
    
    然而,如果您正在转换大量代码(如果您真的必须转换它,请参见下文),那么您应该真正了解更多关于LINQ的信息。你最终一定会使用它,如果你了解它是如何工作的,你将处于一个更好的位置来研究如何进行转换。最新的C#图书包括LINQ;如果你有我自己的书(C#深入),那么第8-11章将涵盖LINQ to Objects需要知道的所有内容


    如果您能够使用VS2008,但只针对.NET2.0,另一种选择是使用它,它是.NET2.0的LINQtoObjects的重新实现。。。现在是:)

    多亏了乔恩·斯凯特,这真的帮了我大忙。它工作得很好,所有的UnitTest都成功通过了

    在这里,我想把答案分享给任何想在.NET2.0中使用域名解析器的人

    1更改此代码(DomainName.cs) 为此:

    List<TLDRule> exceptionresults = MatchRule(TLDRulesCache.Instance.TLDRuleList, checkAgainst, TLDRule.RuleType.Exception);
    List<TLDRule> wildcardresults = MatchRule(TLDRulesCache.Instance.TLDRuleList, checkAgainst, TLDRule.RuleType.Wildcard);
    List<TLDRule> normalresults = MatchRule(TLDRulesCache.Instance.TLDRuleList, checkAgainst, TLDRule.RuleType.Normal);
    
        private static List<TLDRule> MatchRule(List<TLDRule> rules, string checkAgainst, TLDRule.RuleType ruleType)
        {
            List<TLDRule> matchedResult = new List<TLDRule>();
            foreach (TLDRule rule in rules)
            {
                if (rule.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                    && rule.Type == ruleType)
                {
                    matchedResult.Add(rule);
                }
            }
            return matchedResult;
        }
    
    进入这个

            TLDRule primaryMatch = null;
            if (ruleMatches.Count > 0)
            {
                // match2 CompareTo match1 (reverse order) to make the descending
                ruleMatches.Sort(delegate(TLDRule match1, TLDRule match2) { return match2.Name.Length.CompareTo(match1.Name.Length); });
                primaryMatch = ruleMatches[0];
            }
    
    List<TLDRule> lstTLDRules = ListTLDRule(lstTLDRuleStrings);
    
        private static List<TLDRule> ListTLDRule(List<string> lstTLDRuleStrings)
        {
            List<TLDRule> lstTLDRule = new List<TLDRule>();
            foreach (string ruleString in lstTLDRuleStrings)
            {
                if (!ruleString.StartsWith("//", StringComparison.InvariantCultureIgnoreCase)
                    &&
                    !(ruleString.Trim().Length == 0))
                {
                    lstTLDRule.Add(new TLDRule(ruleString));
                }
            }
            return lstTLDRule;
        }
    
    3更改此设置(TLDRulesCache.cs)
    IEnumerable lstTLDRules=来自lsttldrulestring中的规则字符串
    哪里
    !ruleString.StartsWith(“/”,StringComparison.InvariantCultureInogoreCase)
    &&
    !(ruleString.Trim().Length==0)
    选择新的TLDRule(规则字符串);
    
    进入这个

            TLDRule primaryMatch = null;
            if (ruleMatches.Count > 0)
            {
                // match2 CompareTo match1 (reverse order) to make the descending
                ruleMatches.Sort(delegate(TLDRule match1, TLDRule match2) { return match2.Name.Length.CompareTo(match1.Name.Length); });
                primaryMatch = ruleMatches[0];
            }
    
    List<TLDRule> lstTLDRules = ListTLDRule(lstTLDRuleStrings);
    
        private static List<TLDRule> ListTLDRule(List<string> lstTLDRuleStrings)
        {
            List<TLDRule> lstTLDRule = new List<TLDRule>();
            foreach (string ruleString in lstTLDRuleStrings)
            {
                if (!ruleString.StartsWith("//", StringComparison.InvariantCultureIgnoreCase)
                    &&
                    !(ruleString.Trim().Length == 0))
                {
                    lstTLDRule.Add(new TLDRule(ruleString));
                }
            }
            return lstTLDRule;
        }
    
    listldrules=listldrule(lstldrulestring);
    私有静态列表ListTLDRule(列表lsttldrulestring)
    {
    List lstTLDRule=新列表();
    foreach(lsttldrulestring中的字符串规则字符串)
    {
    如果(!ruleString.StartsWith(“/”,StringComparison.InvariantCultureIgnoreCase)
    &&
    !(ruleString.Trim().Length==0))
    {
    添加(新的TLDRule(规则字符串));
    }
    }
    返回lstTLDRule;
    }
    
    还有一些是小事情,比如:

    List<string> lstDomainParts = domainString.Split('.').ToList<string>();
    
    List lstDomainParts=domainString.Split('.').ToList();
    
    改为:

    List<string> lstDomainParts = new List<string>(domainString.Split('.'));
    
    List lstDomainParts=新列表(domainString.Split('.');
    
    并删除与中类似的.ToList()

    “var exceptionresults”将使用exceptionresults.ToList()获取列表。由于“var exceptionresults”更改为“List exceptionresults”。ToList()应被删除


    Callmelan

    感谢您的快速响应。它似乎起作用了。现在我想将IEnumerable更改为List,这样我就可以像wildcardresults.Count一样使用它。因此,新语句变成:List exceptionresults=(List)MatchExceptions(TLDRulesCache.Instance.TLDRuleList,checkback);因为我无法将方法IEnumerable MatchExceptions()更改为List MatchExceptions(),因为使用了关键字“yield”。我想你指的是类型。我没有看到任何代码改变checkback值。Oic,这是收益率的意思。TQVM。只是我编辑的另一个代码。我混淆了“orderby”。不同的情况。我不知道如何在if语句中进行比较,以测试match.Name.Length是否与上一个匹配对象进行比较。差不多了,这是什么意思?TLDRule primaryMatch=results.Take(1).SingleOrDefault()我认为Take 1可能是第一个,results[0]。什么是SingleOrDefault()?我认为用这种方式逐条解释整个LINQ是徒劳的。我强烈建议您从书本或教程中了解LINQ。我得到了以下信息:ruleMatches.Sort(委托(TLDRule match1,TLDRule match2){返回match2.Name.Length.CompareTo(匹配
    List<string> lstDomainParts = new List<string>(domainString.Split('.'));