2

我非常理解 ConcurentQueue 集合。如果 T 是类或结构,如何在 ConcurrentQueue 中使用 Contains 方法?

我的代码:

    namespace lab2Form
    {
        struct DomainName
        {
            public string domainName;
            public ulong domainNameCounter;
        }

        class LogStruct
        {
            public ConcurrentQueue<DomainName> domainNameQueue;
            //some code

            public LogStruct()
            {
                domainNameQueue = new ConcurrentQueue<DomainName>() { };
                //some code
            }
        }

        class CLogParser
        {
            LogStruct m_logStruct;

            public CLogParser()
            {
                 m_logStruct = new LogStruct();
            }

            public void ThreadProc(object param)
            {
                //...
                string line;
                while ((line = file.ReadLine()) != null)
                {
                    var space_pos = line.IndexOf(' ');
                    if (space_pos > 0)
                    {
                      string[] parameters = line.Split(new Char[] { ' ' },            StringSplitOptions.RemoveEmptyEntries);
                      string domainName = parameters[0];
                      if (m_logStruct.domainNameQueue.Contains<DomainName>(domainName))//I can't understand how to build this code-string correctly
                      {
                      }
               //...
}

如何正确使用并发队列中的包含方法?

4

3 回答 3

2

尝试m_logStruct.domainNameQueue.Any(d => d.domainName == domainName)

于 2014-10-20T19:16:32.983 回答
1

您正在传递一个字符串,而 Contains 方法需要一个域名。这应该编译:

m_logStruct.domainNameQueue.Contains<DomainName>(new DomainName {domainName = domainName})

但是,如果您想检查 domainName 是否相等,这将不是很有用。您可以覆盖 DomainName 中的 Equals:

struct DomainName
{
    public string domainName;
    public ulong domainNameCounter;

    public override bool Equals(object obj)
    {
        if (obj is DomainName)
        {
            return ((DomainName) obj).domainName == domainName;
        }

        return false;
    }
}
于 2014-10-20T19:15:06.123 回答
1

如果您只想将domainName字段视为队列中的唯一标识字段,请覆盖EqualsGetHashCode喜欢:

struct DomainName : IEquatable<DomainName>
{
    public string domainName;
    public ulong domainNameCounter;

    public bool Equals(DomainName other)
    {
        return string.Equals(domainName, other.domainName);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        return obj is DomainName && Equals((DomainName) obj);
    }

    public override int GetHashCode()
    {
        return (domainName != null ? domainName.GetHashCode() : 0);
    }
}

然后你可以这样做:

LogStruct m_logStruct = new LogStruct();
m_logStruct.domainNameQueue.Enqueue(new DomainName() {domainName = "ABC", domainNameCounter = 1});
m_logStruct.domainNameQueue.Enqueue(new DomainName() {domainName = "DEF", domainNameCounter = 1});

if (m_logStruct.domainNameQueue.Contains(new DomainName() {domainName = "ABC", domainNameCounter = 1}))
{
    Console.WriteLine("Already exists");
}

否则Contains只会比较引用。

如果您想包含这两个字段domainNamedomainNameCounter然后将这两个字段都包含在EqualsGetHashCode实施中。

如果您不想覆盖Equals并且GetHashCode不能使用Contains (without IEqualityComparer<DomainName>),则必须遍历队列并检查是否有任何项目domainName与您的 new 匹配domainName。通过 LINQ,您可以使用:

bool ifExist = m_logStruct.domainNameQueue.Any(d => d.domainName == domainName);

(就像@Peter Duniho的回答中指定的那样)

于 2014-10-20T19:24:04.610 回答