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
                      {
                      }
               //...
}

並行キューでcontainsメソッドを正しく使用するには?

4

3 に答える 3

2

試すm_logStruct.domainNameQueue.Any(d => d.domainName == domainName)

于 2014-10-20T19:16:32.983 に答える
1

Contains メソッドが DomainName を期待しているときに、文字列を渡しています。これはコンパイルする必要があります:

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フィールドをキュー内の一意に識別するフィールドとしてのみ考慮したい場合は、オーバーライドEqualsして次GetHashCodeのようにします。

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は、参照のみを比較します。

両方のフィールドを含めてから、実装に両方のフィールドdomainNameを含める場合。domainNameCounterEqualsGetHashCode

Equalsオーバーライドしたくない場合は( なしで)GetHashCode代わりに使用できない場合は、代わりにキューをループして、アイテムがnew に一致するかどうかを確認する必要があります。LINQ を使用すると、次を使用してそれを行うことができます。Contains IEqualityComparer<DomainName>domainNamedomainName

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

(@Peter Dunihoの回答で指定されているように)

于 2014-10-20T19:24:04.610 に答える