Использование Содержит метод<T> в ConcurrentQueue, если T является классом или структурой
Я плохо понимаю коллекцию ConcurentQueue. Как использовать метод Contains в ConcurrentQueue, если T является классом или структурой?
Мой код:
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
{
}
//...
}
Как правильно использовать метод содержит в параллельном очереди?
3 ответа
Вы передаете строку, в то время как метод Contains ожидает имя_домена. Это должно скомпилировать:
m_logStruct.domainNameQueue.Contains<DomainName>(new DomainName {domainName = domainName})
Однако это не будет очень полезно, если вы хотите проверить на равенство domainName. Вы можете переопределить Equals в DomainName:
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;
}
}
Пытаться m_logStruct.domainNameQueue.Any(d => d.domainName == domainName)
Если вы только хотите рассмотреть 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
а также domainNameCounter
затем включите оба поля в Equals
а также GetHashCode
реализация.
Если вы не хотите переопределять Equals
а также GetHashCode
тогда вы не можете использовать Contains
(безIEqualityComparer<DomainName>
) вместо этого вы должны пройти через вашу очередь и проверить, есть лиdomainName
соответствует вашему новомуdomainName
, Через LINQ вы можете сделать это, используя:
bool ifExist = m_logStruct.domainNameQueue.Any(d => d.domainName == domainName);
(как указано в ответе @Peter Duniho)